regex 为什么星号(*)在这个正则表达式中表现得像一个惰性结构?[重复]

yvfmudvl  于 2023-04-13  发布在  其他
关注(0)|答案(1)|浏览(99)

此问题已在此处有答案

Can someone explain Possessive Quantifiers to me? (Regular Expressions)(1个答案)
昨天关门了。
为了好玩,我写了一个简单的正则表达式引擎,但这打破了对*\**的理解。正则表达式:

/a*abc/

输入:

abc

In my head and my engine/a*abc/

  • a*是0或更大的时间
  • a一次
  • b一次
  • c一次

因此,当我在abc上执行时,我认为第一个a*消耗了第一个a,剩下的是bc,没有更多的a并进入下一个FSM状态,需要abca,但输入是bc,结果不匹配。
就像这样:

1)
regex:
  a*abc
  ^^
input
  abc
  ^

a* consume a {0,N}

2)
regex:
  a*abc
    ^
input
  abc
   ^

no match.

如果在此匹配中添加惰性运算符:

/a*?abc/
  • a*?为0或更长时间,此时不满足下一状态
  • a一次
  • b一次
  • c一次

因此,当我在abc上执行时,我认为第一个a*?不会首先消耗a,因为abc满足下一个规则。
就像这样:

1)
regex:
  a*?abc
  ^^^
input
  abc
  ^

a*? not consume a because a satisfied next rule a

2)
regex:
  a*?abc
     ^
input
  abc
  ^

3)...4)... match

但是什么呢?在真实的世界中,例如,PCRE引擎,*更像是一个懒惰的操作符:首先,a*不消耗a,跳过状态并直接匹配abc。因此,/a*abc/应该在abc上匹配true。
为什么第一个贪婪的状态a*不消耗输入?{0,}像懒惰的运算符一样工作吗?

insrf1ej

insrf1ej1#

当你的第一个正则表达式在第二步不匹配时,它会返回到第一步(匹配a*部分),并给予一个匹配的符号并尝试继续。
贪婪与懒惰在这种情况下意味着尽可能多地(尽可能少地)获取**。由于首先获取a并且仍然不可能匹配,因此它将给予它。
你所描述的是PCRE的所有格修饰符行为:a*+abc将完全按照您所描述的工作:它会拿走所有匹配的东西,而不会给予任何东西。
给你个建议如果你打算
编写一个简单的正则表达式引擎
考虑彻底至少学习this

相关问题