关于正则表达式力学的基本问题:
我有以下表达式:[10]*1[10]*
。
这匹配100
吗?
我的理由:
第一个选项:[10]*
匹配“100”,然后到达字符串=>的末尾没有比赛。
第二个选项:[10]*
被忽略,表达式匹配。
我是否忘记了一些微不足道的事情,或者这实际上取决于正则表达式引擎? (我记得有关贪婪和贪婪的事情,但我不确定这是否适用于这种情况)
答案 0 :(得分:2)
答案是,是的,它匹配,因为正则表达式解析器将消耗每个子表达式所需的数量,因为它需要在整个表达式上实现匹配。
在您的情况下,要匹配它将执行此操作:
[10]*
将消耗零字符1
[10]*
将消耗剩余的输入
最后,不要在这里问,为什么不在regexpal上试一试,亲自看看!
答案 1 :(得分:2)
正则表达式引擎会回溯。
引擎尝试将100
与[10]*
匹配,但这不起作用,因为1
无法匹配。但随后引擎会丢弃重复的最后一个字符(仅[10]*
使用10
)并再次尝试。仍然无效,因为1
与0
不匹配。引擎将一次丢弃一个字符,直到第一个[10*]
完全丢弃。现在1
匹配,[10]*
很乐意与其他匹配。
我建议您通过this tutorial阅读,因为它解释了非常以及在幕后发生了什么。 (对于您的特殊问题,请查看重复部分。)
更多细节:
这不取决于重复是贪婪还是不真实。正则表达式引擎将始终回溯。它只会从另一端([10]
出现0次)开始,如果你不这样做的话:[10]*?
。在这种情况下,这将加快过程,因为第一次尝试已经匹配,但它不会改变事实,它总是匹配。
事实上,您可以通过重复“占有”来手动阻止引擎回溯。如果你这样做,并且首先重复,那么引擎将不会尝试其他可能的重复。这将是语法:[10]*+
。现在,引擎只会与第一部分匹配100
。然后匹配1
会失败,但由于你重复占有,所以不会再尝试使用[10]*
的不同选项。当然,在这种情况下,这是无用的,但是存在需要这种行为的用例。所有这些也包含在链接教程中。 ;)
答案 2 :(得分:1)
这很容易测试。这是一个小小的PHP脚本:
<?php
if (preg_match('/[10]*1[10]*/', '100')) {
echo "It matches.\n";
} else {
echo "It doesn't match.\n";
}
?>
输出是:
It matches.
解释:在对regex引擎进行一些试验和回溯之后,最终结果是第一个[10]*
不匹配。 1
与文字1
匹配,第二[10]*
与文字00
匹配。