gpt4 book ai didi

ruby - Ruby 1.9 正则表达式是否与上下文无关语法同样强大?

转载 作者:数据小太阳 更新时间:2023-10-29 06:39:38 25 4
gpt4 key购买 nike

我有这个正则表达式:

regex = %r{\A(?<foo> a\g<foo>a | b\g<foo>b | c)\Z}x

当我针对多个字符串测试它时,它似乎与上下文无关语法一样强大,因为它正确地处理了递归。

regex.match("aaacaaa")
# => #<MatchData "aaacaaa" foo:"aaacaaa">
regex.match("aacaa")
# => #<MatchData "aacaa" foo:"aacaa">
regex.match("aabcbaa")
# => #<MatchData "aabcbaa" foo:"aabcbaa">
regex.match("aaacaa")
# => nil

"Fun with Ruby 1.9 Regular Expressions "有一个例子,他实际上安排了一个正则表达式的所有部分,使其看起来像一个上下文无关的语法,如下所示:

sentence = %r{ 
(?<subject> cat | dog | gerbil ){0}
(?<verb> eats | drinks| generates ){0}
(?<object> water | bones | PDFs ){0}
(?<adjective> big | small | smelly ){0}

(?<opt_adj> (\g<adjective>\s)? ){0}

The\s\g<opt_adj>\g<subject>\s\g<verb>\s\g<opt_adj>\g<object>
}x

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

最佳答案

这是 Ruby 1.9 中使用的 Oniguruma 正则表达式引擎的一大优点——它具有解析器的强大功能,并且不限于识别常规语言。它具有正面和负面的前瞻/后视功能,甚至可以用来识别一些不是上下文无关的语言!以下面为例:

regexp = /\A(?<AB>a\g<AB>b|){0}(?=\g<AB>c)a*(?<BC>b\g<BC>c|){1}\Z/

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

(一个限制:您不能在先行和后行中使用命名组。)

虽然我没有深入了解,但 Oniguruma 似乎通过简单的递归下降来处理命名组,当某些东西不匹配时备份。我观察到它不能处理左递归。例如:

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

我不太清楚我的解析理论,但我认为像这样的非确定性自顶向下解析器应该能够解析任何上下文无关语言。 (“语言”,而不是“语法”;如果您的语法是左递归,则必须将其转换为右递归。)如果不正确,请编辑这篇文章。

关于ruby - Ruby 1.9 正则表达式是否与上下文无关语法同样强大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8959295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com