我使用regex101分析了这两个正则表达式。 我认为/\S+:/
的回溯是正确的。 但是我不明白其中的区别。 我错了吗?
我使用regex101分析了这两个正则表达式。 我认为/\S+:/
的回溯是正确的。 但是我不明白其中的区别。 我错了吗?
这是一种名为自动占有化
的pcre优化。
PCRE的“自动占有化”优化通常适用于模式末尾(以及内部)的字符重复。例如,模式“
a\d+
”被编译为“a\d++
”,因为甚至考虑回溯到重复的数字是没有意义的。
和
由于例如,这是一种优化,将
a+b
转换为a++b
,以避免进入无法成功的a+
的回溯。
:
不包含在 \w
中,所以您的模式被解释为 \w++:
(第二个 +
避免回溯,参见占有量词)。额外的回溯状态被避免,因为没有另一个状态可以匹配。:
包含在 \S
中,因此这种优化不适用于第二种情况。
你可以使用pcretest
来查看差异 (这里有一个Windows版本可以下载here)。
模式/\w+:/
需要11个步骤,输出结果为:
/\w+:/
--->get accept:
+0 ^ \w+
+3 ^ ^ :
+0 ^ \w+
+3 ^ ^ :
+0 ^ \w+
+3 ^^ :
+0 ^ \w+
+0 ^ \w+
+3 ^ ^ :
+4 ^ ^ .*
+6 ^ ^
0: accept:
(*NO_AUTO_POSSESS)
,禁用此优化,模式/(*NO_AUTO_POSSESS)\w+:/
将花费14步并输出:/(*NO_AUTO_POSSESS)\w+:/
--->get accept:
+18 ^ \w+
+21 ^ ^ :
+21 ^ ^ :
+21 ^^ :
+18 ^ \w+
+21 ^ ^ :
+21 ^^ :
+18 ^ \w+
+21 ^^ :
+18 ^ \w+
+18 ^ \w+
+21 ^ ^ :
+22 ^ ^ .*
+24 ^ ^
0: accept:
- 它比\S+
少1步,这是预期的,因为\w+
不匹配:
。
很遗憾regex101不支持这个动词。
更新: regex101现在支持这个动词,以下是比较3个案例的链接:
/\S+:/
(14步) - https://regex101.com/r/cw7hGh/1/debugger
/\w+:/
(10步) - https://regex101.com/r/cw7hGh/2/debugger
/(*NO_AUTO_POSSESS)\w+:/
(13步) - https://regex101.com/r/cw7hGh/3/debugger
regex101调试器:
尽管这似乎是实现特定的(RegexBuddy没有显示这种行为),但可以解释如下:
\w
不能匹配:
,但\S
可以。 因此,在确认get
无法匹配之前,\S +:
需要检查更多输入字符串的变化。
优化更多的正则表达式引擎将更快地排除不可能的匹配项(例如,当正则表达式包含在当前匹配的一部分中不存在的字面字符时), 但显然regex101使用的引擎并未这样做。