我意外地回溯+
了 Raku 正则表达式的量词。
在这个正则表达式中:
'abc' ~~ m/(\w+) {say $0} <?{ $0.substr(*-1) eq 'b' }>/;
say $0;
我得到了预期的结果:
「abc」 # inner say
「ab」 # inner say
「ab」 # final say
也就是说,(贪婪)+
量词获取所有字母,然后条件失败。之后,它通过释放最后一个得到的字母开始回溯,直到条件评估为真。
但是,当我将量词放在捕获组之外时,回溯的工作方式似乎不同:
'abc' ~~ m/[(\w)]+ {say $0} <?{ $0.tail eq 'b' }>/;
say $0;
结果:
[「a」 「b」 「c」] # inner say
[「a」 「b」 「c」] # why this extra inner say? Shouldn't this backtrack to [「a」 「b」]?
[「a」 「b」 「c」] # why this extra inner say? Shouldn't this backtrack to [「a」 「b」]?
[「b」 「c」] # Since we could not successfully backtrack, We go on matching by increasing the position
[「b」 「c」] # Previous conditional fails. We get this extra inner say
[「c」] # Since we could not successfully backtrack, We go on matching by increasing the position
Nil # final say, no match because we could not find a final 'b'
这种行为是预期的吗?如果是这样:为什么它们的工作方式不同?是否可以模仿第一个正则表达式但仍将量词保留在捕获组之外?
笔记:
使用惰性量词“解决”问题......这是预期的,因为差异似乎发生在回溯中,而惰性量词不会发生这种情况。
'abc' ~~ m/[(\w)]+? {say $0} <?{ $0.tail eq 'b' }>/;
[「a」]
[「a」 「b」]
[「a」 「b」]
但是出于性能原因,我宁愿使用贪婪的量词(这个问题中的例子是一个简化)。