首页 新闻 会员 周边 捐助

贪婪没回溯例子

0
[已解决问题] 解决于 2025-07-26 11:33

"abc11ddabc11" =~ =~/([a-z]*)([0-9]*)dd\1\2/
print "first group \1: $1\n";
print "second group \2: $2\n";

_java_python的主页 _java_python | 小虾三级 | 园豆:984
提问于:2025-07-26 11:28
< >
分享
最佳答案
0

在这个特定的匹配中确实没有发生回溯。让我详细解释为什么:

匹配过程(无回溯版本):
text
字符串: a b c 1 1 d d a b c 1 1
位置: 0 1 2 3 4 5 6 7 8 9 10 11
([a-z]*):

从位置0开始匹配

匹配 a (位置0) → 成功

匹配 b (位置1) → 成功

匹配 c (位置2) → 成功

遇到 1 (位置3,非字母) → 停止

$1 = "abc"

当前匹配结束位置:3

([0-9]*):

从位置3继续

匹配 1 (位置3) → 成功

匹配 1 (位置4) → 成功

遇到 d (位置5,非数字) → 停止

$2 = "11"

当前匹配结束位置:5

dd:

匹配位置5的 d → 成功

匹配位置6的 d → 成功

当前匹配结束位置:7

\1 (需要匹配 "abc"):

位置7: a → 匹配

位置8: b → 匹配

位置9: c → 匹配

成功,当前位置:10

\2 (需要匹配 "11"):

位置10: 1 → 匹配

位置11: 1 → 匹配

成功,字符串结束

为什么没有回溯?
完美顺序匹配:

每个部分都一次性匹配成功

没有需要"重试"的部分

贪婪量词恰到好处:

[a-z]* 在字母结束时停止(位置3)

[0-9]* 在数字结束时停止(位置5)

没有"多吃"需要吐出的情况

反向引用完美对应:

后面的 abc 正好在 dd 之后(位置7-9)

最后的 11 正好在 abc 之后(位置10-11)

如果字符串稍有不同,就可能触发回溯:

例1:字符串改为 "abc11ddab11" =~/([a-z]*)([0-9]*)dd\1\2/
text
步骤1-3相同:$1="abc", $2="11", 匹配"dd"到位置7
步骤4:\1 需要匹配 "abc"
但位置7-8是 "ab" → 失败
回溯发生:
尝试减少 $2 的匹配:
原 $2="11" → 改为 $2="1" (只匹配位置3的'1')
此时 $2="1",位置停在4
匹配 "dd":位置4是'1' ≠ 'd' → 失败
继续回溯:减少 $1 的匹配
$1="ab" (只匹配到位置2)
然后 $2 匹配位置2-4的 "c11" → 但 [0-9]* 不能匹配字母'c' → 失败
最终匹配失败
例2:字符串改为 "abc11ddac11" =~/([a-z]*)([0-9]*)dd\1\2/
text
步骤1-3相同:$1="abc", $2="11", 匹配"dd"到位置7
步骤4:\1 需要匹配 "abc"
位置7-9是 "ac" → 失败
回溯:尝试减少 $2 的匹配
设 $2="1" (只匹配位置3)
则 "dd" 需要匹配位置4-5 → 但位置4是'1'≠'d' → 失败
回溯:减少 $1 的匹配
设 $1="ab" (匹配到位置2)
然后 $2 匹配位置2-4的 "c11" → [0-9]* 不能匹配字母'c' → 失败
最终匹配失败

_java_python | 小虾三级 |园豆:984 | 2025-07-26 11:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册