Ruby 1.9.1 は次の正規表現をサポートしています。
regex = %r{ (?<foo> a\g<foo>a | b\g<foo>b | c) }x
p regex.match("aaacbbb")
# the result is #<MatchData "c" foo:"c">
「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.1 の正規表現エンジン (鬼車の正規表現エンジン) が実際には文脈自由文法と同等であることを意味していると思いますが、キャプチャー グループは実際のパーサー ジェネレーターほど有用ではありません。
これは、「文脈自由言語のポンピング補題」は、Ruby 1.9.1 の正規表現エンジンが認識できる言語のクラスを記述する必要があることを意味します。
編集:おっと!私はめちゃくちゃになり、実際に上記の私の答えを完全に間違ったものにする重要なテストを行いませんでした。回答は有用な情報であるため、削除しません。
regex = %r{\A(?<foo> a\g<foo>a | b\g<foo>b | c)\Z}x
#I added anchors for the beginning and end of the string
regex.match("aaacbbb")
#returns nil, indicating that no match is possible with recursive capturing groups.
EDIT:何ヶ月も後にこれに戻ってきて、最後の編集での私のテストが間違っていたことを発見しました. 文脈自由文法のように動作する場合でも、"aaacbbb"
一致することを期待すべきではありません。regex
regex
正しいテストは のような文字列で行う必要があり"aabcbaa"
、正規表現と一致します。
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">