正则表达式与优先级怪异匹配



在用php编写变形脚本时,我遇到了一种奇怪的(至少对我来说)行为。似乎我的正则表达式包含许多不同的词尾模式,即使第一个选项完全可以,也与第二个可接受的选项相匹配。

完整的表达式是这样的(你真的不需要注意这个):

([kpt])1([aou])$|(?:(n)t)?([auo])$|([aeou][^aeiouyäö]+[aeiou])$|([auo][^aeiouyäö]+)$|([^aeiouyäö])(?!6)([^aeiouyäö])(e)$|((?:[auo]i|[auo])[^aeiouyäö]*)([aeiouyäö])10$

不用说,我先是怀疑自己在某处犯了错误,于是我一点一点地把表情弄糊涂了,最后到了这个阶段:

([aeiou])$|(.+)$

字面意思应该是"匹配字符串末尾的一个元音并将其用作反向引用 1,或者如果失败,则在字符串末尾之前匹配任意字符多次并将其用作反向引用 2"

当与像foo这样的字符串一起使用时,我希望使用表达式的第一部分(([aeiou])$)。相反,使用了第二个,这让我感到困惑。

如果删除量词,则使用第一个选项。我猜这与表达部分的贪婪或特异性有关,尽管我认为表达式是从左到右测试的。

有人可以向我解释这种行为吗?

匹配字符串末尾的一个元音 [...] 或者如果失败,则在字符串末尾之前匹配任意字符次数 [...]

不,这不是它的意思。正确的解释是:

匹配以下较长的:

  • 字符串末尾的一个元音
  • 字符串末尾前任意次数的任何字符

(我不知道平局规则是否很明确。

最新更新