Ruby 1.9正则表达式对于无上下文语法同样强大吗?

我有这个正则表达式:

regex = %r{\A(? a\ga | b\gb | c)\Z}x 

当我针对几个字符串测试它时,它看起来像上下文无关语法一样强大,因为它正确处理递归。

 regex.match("aaacaaa") # => # regex.match("aacaa") # => # regex.match("aabcbaa") # => # regex.match("aaacaa") # => nil 

“ Ruby 1.9正则表达式的乐趣 ”有一个例子,他实际上安排了正则表达式的所有部分,使它看起来像一个无上下文的语法,如下所示:

 sentence = %r{ (? cat | dog | gerbil ){0} (? eats | drinks| generates ){0} (? water | bones | PDFs ){0} (? big | small | smelly ){0} (? (\g\s)? ){0} The\s\g\g\s\g\s\g\g }x 

在他重新排列正则表达式部分的技术和我的递归命名捕获组的例子之间,这是否意味着Ruby 1.9正则表达式具有与无上下文语法相当的能力?

这是关于Ruby 1.9中使用的Oniguruma regexp引擎的一个很棒的东西 – 它具有解析器的强大function,并且不仅限于识别常规语言。 它具有正面和负面的前瞻/外观,甚至可用于识别一些不具有上下文的语言! 以下面的例子为例:

 regexp = /\A(?a\gb|){0}(?=\gc)a*(?b\gc|){1}\Z/ 

此正则表达式识别“abc”,“aabbcc”,“aaabbbccc”等字符串 – “a”,“b”和“c”的数量必须相等,否则它们将不匹配。

(一个限制:你不能在前瞻和后方使用命名组。)

虽然我没有偷看,但Oniguruma似乎通过简单的递归下降处理命名组,当事情不匹配时备份。 我发现它不能处理左递归。 例如:

 irb(main):013:0> regexp = /(?\ga|)/ SyntaxError: (irb):13: never ending recursion: /(?\ga|)/ from C:/Ruby192/bin/irb:12:in `
'

我不太清楚地记得我的解析理论,但我认为像这样的非确定性自上而下的解析器应该能够解析任何无上下文的语言。 (“语言”,而不是“语法”;如果您的语法已经离开递归,则必须将其转换为正确的递归。)如果这不正确,请编辑此post。

Interesting Posts