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