Ruby正規表現の後読みでは長さ不定の量指定子は原則使えない

こんにちは、hachi8833です。「ライフ」カテゴリの記事でアドベント書きたかったのですが、こちらの小ネタにします。 正規表現の先読みと後読みについては「正規表現の先読み・後読み(look ahead、look behind)を活用しよう」をご覧ください。 以下は基本的にRubyの正規表現(onigmo)を使います。他の正規表現ライブラリではこのとおりにならない可能性があります。 Rubyの正規表現の後読みは長さを不定にできない 以下の文字列が対象です。 word work wording working interesting partitioning subscribe subscriber subscription たとえば、ingで終わる1文字以上の長さの英単語のingだけにマッチさせたいと思って次の正規表現を書いたとします。+は1文字以上のマッチを表します。 (?<=[\p{L}]+)ing しかしやってみると、Invalid pattern in look-behind.と表示されます。なお、+を最小一致の+?に変えてもだめでした。 Rubular 任意の長さの代わりに、長さの異なる特定の語のリストを後読みで使うとどうなるでしょうか。 (?<=(word|work|interest|partition))ing これも同じくInvalid pattern in look-behind.になります。なお、リスト内の各語の長さをすべて同じにすると通ります。 Rubular 後読みは本体がマッチした後で文字どおり遡ってチェックされるはずなので、量指定子(quantifier: 量化子とも呼ばれます)の長さが不定だと効率が非常に落ちることは想像がつきます。Onigmoの仕様まではチェックしていませんが、おそらくそうした理由で長さ不定の後読みをサポートしていないのではないかと推測しています。 ちょっとだけPerlでも試してみましたが、こちらもnot implementedだそうです。 $ perl -e ‘”word work wording working interesting partitioning subscribe subscriber subscription” =~ /(?<=[\\p{L}]+)ing/;’ Variable length lookbehind not implemented in regex … Continue reading Ruby正規表現の後読みでは長さ不定の量指定子は原則使えない