其实我理解什么是回溯,就是引擎应用贪婪量词时的状态,导致其他原子失败,所以引擎开始回溯到之前的状态,逐渐放弃匹配,以匹配剩余的原子.
但是在这个 "abcv
上使用此模式 "[^"]*"
时,我得到了意外的行为,我编写它是为了检查失败时会发生什么。我希望引擎采取这些步骤:
- 引擎匹配
“
- 那么贪婪量化的否定字符集将匹配 abcv
- 引擎无法匹配最后一个
”
- 所以它应该回溯到
[^"]*
,一一放弃字符,尝试匹配剩余的原子。
但是当我在 regex101 上测试这个时,引擎不会回溯,但每次失败时它都会从另一个位置重新开始。那么我在这里缺少什么?
这确实是我们所期望的吗?如果是这样,有人能解释一下为什么吗?
Update
我需要提到 ".*"
会回溯,如果您检查引擎步骤,您会发现它开始一一给出字符,但有问题的字符却不会。为什么会出现这种差异,而 .*
和 [^"]*
都是匹配相同文本的贪婪量词,但一个必须回溯,另一个则不然。
最佳答案
PCRE 在这里使用“自动占有”优化,因为它“看到”除了两个 ”
之间的 ”
之外,没有办法匹配任何其他字符。请参阅PCRE docs :
PCRE_NO_AUTO_POSSESS
If this option is set, it disables "auto-possessification". This is an optimization that, for example, turns a+b into a++b in order to avoid backtracks into a+ that can never be successful. However, if callouts are in use, auto-possessification means that some of them are never taken. You can set this option if you want the matching functions to do a full unoptimized search and run all the callouts, but it is mainly provided for testing purposes.
您可以easily check通过在 "[^"]*"
前面添加 (*NO_AUTO_POSSESS)
PCRE 动词:
关于regex - 为什么在使用带有否定字符集的星号时不进行回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55334397/