Php 要在首次找到子模式时停止的正则表达式
让我们考虑下面两个例子Php 要在首次找到子模式时停止的正则表达式,php,regex,Php,Regex,让我们考虑下面两个例子 preg_match('/^(\pL+)(?:bcd|cd|d)$/u', 'abcd', $matches); preg_match('/^(\pL+)(?:d|cd|bcd)$/u', 'abcd', $matches); 两个示例都将“abc”作为$matches[1]返回 为什么regex不首先在不匹配的组中找到子模式?是否可以在“bcd”处停止并获取“a”,因为$matches[1]?您可以使用: preg_match('/^(\pL+?)(?>bcd|
preg_match('/^(\pL+)(?:bcd|cd|d)$/u', 'abcd', $matches);
preg_match('/^(\pL+)(?:d|cd|bcd)$/u', 'abcd', $matches);
两个示例都将“abc”作为$matches[1]
返回
为什么regex不首先在不匹配的组中找到子模式?是否可以在“bcd”处停止并获取“a”,因为$matches[1]
?您可以使用:
preg_match('/^(\pL+?)(?>bcd|cd|d)$/u', 'abcd', $matches);
print_r($matches);
输出:
是,通过使
+
量词非贪婪:
preg_match('/^(\pL+?)(?:bcd|cd|d)$/u', 'abcd', $matches);
preg_match('/^(\pL+?)(?:d|cd|bcd)$/u', 'abcd', $matches);
要完成其他答案,以下是发生情况的示意图说明: str | pattern | state | description ------+----------------------+-----------+----------------------------------------- abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS | all letters are matched by \pL+ (greedy) abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | there is no more character abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem abcd | ^(\pL+)(?:bcd|cd|d)$ | BACKTRACK | \pL+ give one character back abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | characters mismatch abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS | abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS | str |模式|状态|描述 ------+----------------------+-----------+----------------------------------------- abcd ^(\pL+)(:bcd | cd | d)$|成功|所有字母都与\pL+(贪婪)匹配 abcd^(\pL+)(:bcd | cd | d)$|失败|没有更多字符 abcd ^(\pL+)(:bcd | cd | d)$| FAIL | idem abcd ^(\pL+)(:bcd | cd | d)$| FAIL | idem abcd^(\pL+)(:bcd | cd | d)$|回溯| \pL+返回一个字符 abcd ^(\pL+)(:bcd | cd | d)$|失败|字符不匹配 abcd ^(\pL+)(:bcd | cd | d)$| FAIL | idem abcd ^(\pL+)(:bcd | cd | d)$|成功| abcd ^(\pL+)(:bcd | cd | d)$|成功| 要理解的最重要的一点是,量词在默认情况下是贪婪的,它可以使用所有字符 注意:这是一个模式。在“现实生活”中,正则表达式引擎逐个字符地工作。在上面的示例中,当测试
bcd
时,regex引擎显然只测试b
,然后失败
注2:在回溯之后,第二个模式不必测试
bcd
和cd
。Regex默认情况下想要贪婪。想想看,你正在尝试匹配表达式。如果它能匹配一个字符,它就会匹配。假设字符串aaaaaaaaaaa
上有/a+a/
。当您可以匹配所有a时,为什么要匹配aa
。可能是出于相同的原因^(\pL+)(:d)$
返回abc
中的$matches[1]。请尝试^(\pL+(:bcd)$
str | pattern | state | description
------+----------------------+-----------+-----------------------------------------
abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS | all letters are matched by \pL+ (greedy)
abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | there is no more character
abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem
abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem
abcd | ^(\pL+)(?:bcd|cd|d)$ | BACKTRACK | \pL+ give one character back
abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | characters mismatch
abcd | ^(\pL+)(?:bcd|cd|d)$ | FAIL | idem
abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS |
abcd | ^(\pL+)(?:bcd|cd|d)$ | SUCCESS |