这是一个众所周知的事实,现代正则表达式实现(最引人注目的是PCRE)与
regular grammars的原始概念很少有共同点。例如,您可以解析一个
context-free grammar {anbn; n> 0}(例如aaabbb):使用该正则表达式(
demo):
~^(a(?1)?b)$~
我的问题是:你能走多远?是否也可以使用PCRE解析context-sensitive grammar {anbncn; n> 0}(例如aaabbbccc)
启发NullUserExceptions答案(他已经删除,因为它失败了一个案例)我想我自己找到一个解决方案:
原文链接:https://www.f2er.com/regex/358026.html$regex = '~^ (?=(a(?-1)?b)c) a+(b(?-1)?c) $~x'; var_dump(preg_match($regex,'aabbcc')); // 1 var_dump(preg_match($regex,'aaabbbccc')); // 1 var_dump(preg_match($regex,'aaabbbcc')); // 0 var_dump(preg_match($regex,'aaaccc')); // 0 var_dump(preg_match($regex,'aabcc')); // 0 var_dump(preg_match($regex,'abbcc')); // 0
自己尝试:http://codepad.viper-7.com/1erq9v
说明
如果你考虑正则表达式没有肯定的前瞻断言((?= …)部分),你有这样:
~^a+(b(?-1)?c)$~
这只是检查有一个任意数量的as,后面跟一个相等数量的bs和cs。
这还不满足我们的语法,因为as的数量也必须相同。我们可以通过检查的数目等于bs的数目来确保。这是前瞻断言中的表达式:(a(? – 1)?b)c。 c是必要的,所以我们不仅匹配bs的一部分。
结论
我认为这令人印象深刻地表明,现代正则表达式不仅能够解析非常规语法,甚至可以解析非上下文无关的语法。希望这将休息无休止的“你不能做X与正则表达式,因为X不是常规”