存在しない正規表現 ~正規表現と秘密の部屋~


この記事は 闇の魔術に対する防衛術 Advent Calendar 2020 の2日目の記事です。

3日目は @Ringa_hyj さんの記事です。

参加しているカレンダーとして完走させたいので、是非参加してください!
枠はまだまだ空いています!


闇の魔術っぽいタイトルにするため、タイトルを一部省略しました。

本記事では (常に検索結果が)存在しない正規表現 を考えてみる記事です。

正規表現は 「文字列内で文字の組み合わせを照合するため」に用いられるもの です。

では、正規表現では無意味なパターン、 「常に照合結果が0件となるパターン」 は作れるでしょうか?
そのようなパターンが作れるのであれば、「実務で使われることがない(意味がない)≒知られていない」ことから、 正規表現の秘密の部屋 といえるでしょう。無理やり

また、関連した内容として、 「常に照合結果が存在するパターン」 と、 「(予想外に)シンタックスエラーとなってしまうパターン」 も存在したので紹介します。

なお、本記事は、ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux] にて動作検証をしています。

常に照合結果が0件となる正規表現

先頭を示すアンカー前に文字クラスがある正規表現

例)/a\A/

irb(main):001:0> "Am I Dead?".match(/a\A/)
=> nil

末尾を示すアンカー後に文字クラスがある正規表現

例)/\zz/

irb(main):002:0> "Am I Dead?".match(/\zz/)
=> nil

単語境界かつ非単語境界の正規表現

例)/\b\B/

irb(main):003:0> "Am I Dead?".match(/\b\B/)
=> nil

&&で作成した存在しない文字クラス

例)/[a&&Z]/

irb(main):004:0> "Am I Dead?".match(/[A&&z]/)
=> nil

矛盾した(否定)先読み

例)/(?!A)A/

irb(main):005:0> "Am I Dead?".match(/(?!A)A/)
=> nil

矛盾した(否定)後読み

例)/A(?<!A)/

irb(main):006:0> "Am I Dead?".match(/A(?<!A)/)
=> nil

任意文字列のアトミックグループ後の任意文字のパターン

例)/(?>.*)./

irb(main):007:0> "Am I Dead?".match(/(?>.*)./)
=> nil

常に照合結果が存在するパターン

ちょうど0回の量指定

例)/.{0}/

irb(main):001:0> "Am I Dead?".match(/.{0}/)
=> #<MatchData "">
irb(main):002:0> "".match(/.{0}/)
=> #<MatchData "">

(予想外に)シンタックスエラーとなってしまうパターン

量指定子の最小が最大より大きい

例)/.{2,1}/

irb(main):001:0> "".match(/.{2,1}/)
Traceback (most recent call last):
        3: from /usr/local/bin/irb:23:in `<main>'
        2: from /usr/local/bin/irb:23:in `load'
        1: from /usr/local/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
SyntaxError ((irb):1: upper is smaller than lower in repeat range: /.{2,1}/)

以上です。他のパターンもあれば、コメント欄などで教えてください!