regex - 为什么在使用带有否定字符集的星号时不进行回溯

标签 regex pcre

其实我理解什么是回溯,就是引擎应用贪婪量词时的状态,导致其他原子失败,所以引擎开始回溯到之前的状态,逐渐放弃匹配,以匹配剩余的原子.

但是在这个 "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 动词:

enter image description here

关于regex - 为什么在使用带有否定字符集的星号时不进行回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55334397/

相关文章:

regex - 将 0(零)附加到 grep 匹配引用

javascript - 零次或多次匹配对于零次匹配无法正常工作

docker - 我应该安装什么包而不是 libpcre++-dev 在 Alpine Golang 中使用 C 代码?

c++ - 如何将 pcre_study 与 pcrecpp 一起使用?

php - 正则表达式 Lookarounds,防止前方和后方

regex - 正则表达式(普通或嵌套括号)

regex - 如何仅在字符串的开头替换重复字符/单词的模式?

Python搜索字符串包含字符

regex - Excel中的表达式语法?

PHP 5.4 安装后 : preg_match(): Compilation failed: unknown option bit(s) set at offset 0