5

关于正则表达式机制的基本问题:

我有以下表达式:[10]*1[10]*.

这会匹配100吗?

我的推理:
第一个选项:[10]*匹配“100”,然后到达字符串的末尾=> 不匹配。
第二个选项:[10]*被忽略并且表达式匹配。

我是否忘记了一些琐碎的事情,或者这实际上取决于正则表达式引擎?
(我记得一些关于贪婪与不贪婪的事情,但我不确定这是否适用于这种情况)

4

3 回答 3

2

正则表达式引擎进行回溯。

引擎尝试与 匹配100[10]*但这不起作用,因为那时1没有可匹配的。但随后引擎会丢弃重复的最后一个字符(仅使用[10]*for 10)并再次尝试。还是不行,因为1不匹配0。引擎将一次丢弃一个字符,直到第一个[10*]完全丢弃。现在1匹配并且[10]*很高兴匹配其余的。

我建议通读本教程,因为它很好地解释了幕后发生的事情。(对于您的特殊问题,请查看重复部分)。

更多细节:

这不取决于重复是贪婪还是不贪婪。正则表达式引擎将始终回溯。[10]如果你让它像这样不贪婪,它将只是从另一端开始(出现 0 次) [10]*?:在这种情况下,这将加快进程,因为第一次尝试已经匹配,但它不会改变它总是匹配的事实。

事实上,您可以通过使重复“占有”来手动防止引擎回溯。如果您这样做,并且首先离开重复,那么引擎将不会尝试其他可能的重复。这将是语法:[10]*+. 现在引擎将100只匹配第一部分。然后匹配1会失败,但是由于您使重复所有格,它不会回去尝试使用不同的选项[10]*。在这种情况下,这当然是无用的,但在某些用例中,这种行为是可取的。所有这些也包含在链接的教程中。;)

于 2012-10-25T19:38:09.733 回答
2

答案是,是的,它匹配,因为正则表达式解析器将从每个子表达式中消耗尽可能多的内容,以实现对整个表达式的匹配。

在你的情况下,匹配它会这样做:

  • 第一个[10]*将消耗零个字符
  • 那么它将匹配文字1
  • 然后最后一个[10]*将消耗剩余的输入


最后,与其在这里问,不如在regexpal上尝试一下,自己看看!

于 2012-10-25T19:37:36.623 回答
1

这很容易测试。这是一个小 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

于 2012-10-25T19:39:57.303 回答