正则表达式含糊不清

时间:2012-10-25 19:34:38

标签: regex

关于正则表达式力学的基本问题:

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

这匹配100吗?

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

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

3 个答案:

答案 0 :(得分:2)

答案是,是的,它匹配,因为正则表达式解析器将消耗每个子表达式所需的数量,因为它需要在整个表达式上实现匹配。

在您的情况下,要匹配它将执行此操作:

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


最后,不要在这里问,为什么不在regexpal上试一试,亲自看看!

答案 1 :(得分:2)

正则表达式引擎会回溯。

引擎尝试将100[10]*匹配,但这不起作用,因为1无法匹配。但随后引擎会丢弃重复的最后一个字符(仅[10]*使用10)并再次尝试。仍然无效,因为10不匹配。引擎将一次丢弃一个字符,直到第一个[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匹配。