正規表現メモ

最終更新日 2022年12月17日

正規表現は使い慣れれば便利なものですが、 ツールによって使える正規表現演算子(メタキャラクタ)に違いがあったりして戸惑うこともあります。 そこで正規表現を扱うツール(や言語処理系)の代表的なものを幾つか選び、 それらのツールで使われている正規表現演算子をまとめてみました。

お断り:

  1. このページでは使い方の例であるとかサンプルといったものは書いていません。
  2. 各処理系の最新バージョン(もしくはその前でも)の情報が反映されていない可能性があります。

Table of contents

  1. grepで使用できる正規表現
  2. egrepで使用できる正規表現 (obsolete)
  3. sedで使用できる正規表現
  4. awkで使用できる正規表現
  5. Perlで使用できる正規表現
  6. Pythonで使用できる正規表現
  7. Rubyで使用できる正規表現
  8. gawk (3.0以降)で使用できる正規表現
  9. Tcl 8.2.3(以降)で使用できる正規表現
  10. PCREで使用できる正規表現 ()
  11. PHPで使用できる正規表現
  12. .NET Frameworkで使用できる正規表現
  13. Javaで使用できる正規表現
  14. JavaScriptで使用できる正規表現
  15. POSIX 1003.2での正規表現について
  16. 各正規表現演算子の説明
  17. 各エスケープシーケンスの説明
  18. ある文字列を含まない正規表現
  19. ReDOS
  20. その他

各種ユーティリティで使える正規表現

grepで使用できる正規表現演算子

GNU grepは、デフォルトではPOSIX 1003.2 (注 現行の規格はもっと新しいものですがこの部分は変わっていません。たぶん) で規定されているBasic Regular Expressionと、 それに加えてGNU grepで拡張されているいくつかの正規表現演算子が使えます。 使用できる正規表現演算子のうち、 \+、\?、\|、\w、\W、\<、\>、\b、\B がGNU grepにおける拡張でありPOSIXの規定にはありません (時折GNU 拡張も含めたものをBREだと書かれたものを見かけますが)。

GNU grep 以外の古いgrepでは[:alnum:]などの表記が使えないかもしれません。 また、GNU grep 2.5以降ではPCREのリンクを有効にしてビルドした場合に PCREを使ったPerl互換の正規表現指定ができます。 PCREによって使うことのできる正規表現については PCREで使える正規表現または PCRE man pageを参照してください。 (PCREが組み込まれた)GNU grepで使用されるPCREのモードはMULTILINEモードです。

POSIXのgrepでは、-Eオプションと共に起動した場合には 正規表現としてExtended Regular Expressionを受付けるようになります。 この場合使用できる演算子には以下のものがあります。

POSIX 1003.2では EREで後方参照が使えるとは定義されていませんが、 GNU grep では使用できます。

egrepで使用できる正規表現演算子

POSIX的にはegrepおよびfgrepはそれぞれgrep -E、grep -Fに置き換えることが推奨されています。 GNU grepをビルドした場合にインストールされるプログラムでも、 egrepやfgrepは対応したオプションを指定してgrepを起動する ラッパーシェルスクリプトに置き換えられています (いつから?)。

GNU grep を egrepという名前で起動したときに使用できる正規表現演算子は以下のものです。 grepに-Eオプションを指定したときと似ていますが、全く同一というわけではありません。 また、通常egrepという名前が付けられているものに比べ、 使用できる演算子が増えているので注意が必要です。
2003年2月21日付記: GNU grep 2.5では-Eオプション指定時の挙動と egrepという名前で起動したときの挙動は同一です。-Eオプション指定時の動作については 前の項を参照してください(2.4あたりでこうなったようです)。

現在現役のシステム上にある、GNU 以外の egrep については調べていません。悪しからず。

sedで使用できる正規表現演算子

POSIX 1003.2で規定されているsedでは以下の演算子が使用できます。

GNU sedでは上記のものに加えて、以下のものが使えます。

付記: GNU sed 4.0.5以降ではオプション指定によりEREを使えるようになります。

'-E'
'-r'
'--regexp-extended'

Use extended regular expressions rather than basic regular expressions. Extended regexps are those that 'egrep' accepts; they can be clearer because they usually have fewer backslashes. Historically this was a GNU extension, but the '-E' extension has since been added to the POSIX standard (http://austingroupbugs.net/view.php?id=528), so use '-E' for portability. GNU sed has accepted '-E' as an undocumented option for years, and *BSD seds have accepted '-E' for years as well, but scripts that use '-E' might not port to other older systems. *Note Extended regular expressions: ERE syntax.

(訳)
basic regular expressionの代わりにextended regular expressionを使用します。 extended regular expressionは'egrep'が受け付けるのと同じもので、 通常basic regular expressionよりも少ないバックスラッシュで記述できるので 正規表現をよりわかりやすいものにできます。 このオプションは歴史的にはGNU固有の拡張でしたが、現在ではPOSIX standard (http://austingroupbugs.net/view.php?id=528) にも追加されているので、移植性のために'-E'を使いましょう。 GNU sedはずっと以前からアンドキュメントなオプションとして '-E'を受け付けるようになっていて、また、*BSDのsedも以前から '-E'を受け付けていました。しかし、その他の古いシステムに'-E'オプションを 使っているスクリプトを持っていくことはできないかもしれません。

GNU sed 4.1.2 では正規表現演算子として\s\Sが使えるようになっています。

undocumented な機能ですが、 GNU sed 4.1.2 以降ではオプション指定によりPerl5互換の正規表現を使えるようになります(有効にしてコンパイルした場合)。 このオプションに関してソースコードに以下のような部分があります。

#ifdef REG_PERL
#define PERL_HELP _("  -R, --regexp-perl" \
                    "\n                 use Perl 5's regular expressions" \
                    " syntax in the script.\n")
#endif

awkで使用できる正規表現演算子

awkでの注意事項
処理系によっては、/[/]/のように、文字クラス指定中に/を置くとエラーとなる場合があります。 これは文字クラスの中に置かれた/を、正規表現を囲む/と取り違えるのが原因です。 そのようなエラーが起きた場合、 \を使ってブラケット内の/をエスケープする必要があります。

補足: gawk 3.0.x 以降では扱える正規表現が拡張されました。 詳しくはgawk 3.0以降で使用できる正規表現演算子を 参照してください。

mawk, Onetrue awkについて追記(予定)

Perlで使用できる正規表現演算子

2017年12月31日時点の最新バージョン 5.26.1
2019年5月1日時点の最新バージョン 5.28.2
2019年12月31日時点の最新バージョン 5.30.1
2022年1月10日時点の最新バージョン 5.34.0

Perlで使用できる正規表現については簡単なリファレンスが perlreref - Perl の正規表現のリファレンス にあります。 また、正規表現に関するチュートリアル perlretut - Perl の正規表現のチュートリアル があります。

そのほか、以下のリストに挙げたような正規表現に関連したドキュメントがあります。

特記事項 → Perlに関する特記事項

以下はPerl5.6で追加されたものです。詳しくは Perl5.6のドキュメント もしくは それ以降のバージョンのドキュメント perlre - Perl 正規表現 - perldoc.jp を参照してください。

\pは後続する名前が表すクラス(プロパティ、スクリプト、ブロック)に属する文字にマッチし、 \Pは後続する名前のクラスに属さない文字にマッチします。 クラスの名前が一文字のときはブレースを省略できます。 クラス名の前に^を置くことにより否定形の指定を行うことも可能です。

Perl 5.8 での変更点

Perl5.8以降(5.6でも使えたようですが)では \p\Pで始まるプロパティ指定に標準Unicode属性を使うこともできます。 詳しくは perlunicode perlunicode - Perl における Unicode サポート を参照してください。 日本語による説明が Unicodestandard にもあります。

Perl 5.8以降ではユーザーが任意のプロパティを作成することができます (IsまたはInを必ず前置)。 詳しくは perlunicode perlunicode - ユーザ定義文字特性 を参照してください。一例をあげると

    sub InKana {
        return <<END;
    3040\t309F
    30A0\t30FF
    END
    }

というサブルーチンを定義することによって、 ひらがな(U+3040からU+309Fの範囲)もしくはカタカナ(U+30A0からU+30FFの範囲)にマッチするプロパティ InKanaを使用できるようになります。 さらにperl 5.8.5ではこのサブルーチン定義において intersection機能を使うことが可能となりました。 詳しくは perlunicode585 perlunicode - ユーザ定義文字特性 を参照してください。

2021年4月追記:

Perl 5.26で日本語表記に関する部分に影響の出る変更があった模様。 Perlで\p{Hiragana}とかが記号にマッチする問題 - Qiita perlunicode - Unicode support in Perl - Perldoc Browser

以下 perldelta - what is new for perl v5.26.0 - metacpan.org からの関連する部分の引用。

Use of \p{script} uses the improved Script_Extensions property

Unicode 6.0 introduced an improved form of the Script (sc) property, and called it Script_Extensions (scx). Perl now uses this improved version when a property is specified as just \p{script}. This should make programs more accurate when determining if a character is used in a given script, but there is a slight chance of breakage for programs that very specifically needed the old behavior. The meaning of compound forms, like \p{sc=script} are unchanged. See "Scripts" in perlunicode.

Perl 5.10.0 での追加

2021年1月追記:

branch reset groups Regex Tutorial - Branch Reset Groups - Alternation With the Same Group Names and Numbers も 5.10 で追加されていました。

perlre - Perl の正規表現 - perldoc.jp より

    (?|pattern)
  

これは各代替分岐において捕捉グループを同じ番号から始める特殊な 属性を持っている、 「ブランチリセット(branch reset)」パターンです。 これは perl 5.10.0 から提供されています。

捕捉グループは左から右へと番号が振られますが、この構成子の内側では 各分岐毎に番号はリセットされます。

各分岐内での番号付けは通常通りに行われ、この構成子の後に続くグループは その中で捕捉グループが一番多かった分岐のみが 格納されていたかのように番号付けされていきます。

この構成子はいくつかの代替マッチングの1つを捕捉したいときに便利です。

以下のパターンを想像してみてください。 下側の番号は内容の格納されるグループを示します。

        # before  ---------------branch-reset----------- after
        / ( a )  (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
        # 1            2         2  3        2     3     4  
  

branch reset を使わなかった場合の番号は次のようになります (単純に左から登場順に番号付け)。

        / ( a )  (   x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
        # 1      2     3         4  5        6     7     8  

もうひとつ Regex Tutorial - Branch Reset Groups - Alternation With the Same Group Names and Numbers からも。

You can have capturing groups before and after the branch reset group. Groups before the branch reset group are numbered as usual. Groups in the branch reset group are numbered continued from the groups before the branch reset group, which each alternative resetting the number. Groups after the branch reset group are numbered continued from the alternative with the most groups, even if that is not the last alternative.

So (x)(?|abc|(d)(e)(f)|g(h)i)(y) defines five capturing groups. (x) is group 1, (d) and (h) are group 2, (e) is group 3, (f) is group 4, and (y) is group 5.

上記引用部分の番号の説明を図にするとこうなります。

  (x) (?| abc | (d) (e) (f) | g (h) i ) (y)
  1             2   3   4       2       5
  |                             |       |
  通常通り                      |        ブランチリセット内の最大値の続き
                               リセットされ再度2から

Perl 5.12.0 時点での変更点

なし?

Perl 5.14.0 時点での変更点

5.14.0 での変更 正規表現

    (?^...) construct signifies default modifiers
  

正規表現中、ASCII キャレット "^" の直後に "(?" があると、 (/i のような)それを囲む修飾子を継承せず、 Perl のデフォルトに戻ることを意味するようになりました。 キャレットに引き続く任意の修飾子はデフォルトを上書きします。

正規表現の文字列化はこの記法を使うようになりました。 例えば、以前は qr/hlagh/i(?i-xsm:hlagh) に 文字列化されていましたが、 (?^i:hlagh) に文字列化されるようになります。

この変更の主な目的は、新しい修飾子が追加されたときに変更する必要のない文字列化に依存したテストが行えるようにすることです。 "Extended Patterns" in perlre を参照してください。

この変更は、文字列化された正規表現を ?-xism を含む固定文字列と 比較しているコードを壊しそうです。

最後のパラグラフの「壊しそうです」はおそらく「壊すかもしれません」 もしくは「壊してしまうかもしれません」の誤訳。

    Add \p{Titlecase} as a synonym for \p{Title}

    (\p{Title} の同義語としての \p{Titlecase})
  

この同義語は、Unicode 特性名である \p{Uppercase} および \p{Lowercase} との対称性のために追加されました。

Starting in Perl 5.14, a "^" (caret or circumflex accent) immediately after the "?" is a shorthand equivalent to d-imnsx . Any positive flags (except "d" ) may follow the caret, so

    (?^x:foo)>
  

is equivalent to

    (?x-imns:foo)>
  

Perl 5.18.0 時点での変更点

Extended Bracketed Character Classesが 5.18 で追加され、 Java などで使えていた文字クラス内での集合演算が可能になった模様 (ただし5.34.0の時点でも「実験的機能」(experimental feature)の段階 perlrecharclass - Perl Regular Expression Character Classes - Perldoc Browser)。

This is a fancy bracketed character class that can be used for more readable and less error-prone classes, and to perform set operations, such as intersection. An example is

    /(?[ \p{Thai} & \p{Digit} ])/
  

This will match all the digit characters that are in the Thai script.

This is an experimental feature available starting in 5.18, and is subject to change as we gain field experience with it.  Any attempt to use it will raise a warning, unless disabled via

  
    no warnings "experimental::regex_sets";
  

The available binary operators are:

     &    intersection
     +    union
     |    another name for '+', hence means union
     -    subtraction (the result matches the set consisting of those
          code points matched by the first operand, excluding any that
          are also matched by the second operand)
     ^    symmetric difference (the union minus the intersection).  This
          is like an exclusive or, in that the result is the set of code
          points that are matched by either, but not both, of the
          operands.

There is one unary operator:

  !    complement

Perl 5.20.0 時点での変更点

New \p{Unicode} regular expression pattern property

Perl 5.22.0 時点での変更点のまとめ

perl5220delta - perl v5.22.0 での変更点 - perldoc.jp

    qr/\b{gcb}/  
  

gcb は「書記素クラスタ境界」(Grapheme Cluster Boundary) のことです。 これは、 その言語のネイティブな話者にとって、単一文字に見えるような 文字の並びの間の境界を見つけるための Unicode 特性です。 Perl は長い間、\X エスケープシーケンスを通してこれらを扱う能力が ありました。 これらを扱うためのもう一つの方法ができました。 詳しくは "\b{}, \b, \B{}, \B" in perlrebackslash を参照してください。

    qr/\b{wb}/
  

wb は「単語境界」(Word Boundary) のことです。 これは単語の境界を探す Unicode 特性です。 これは普通の \b (中かっこなし) と似ていますが、自然言語処理に より適しています。 これは、例えばアポストロフィが単語の中に現れることがあるということを 知っています。 詳しくは "\b{}, \b, \B{}, \B" in perlrebackslash を参照してください。

    qr/\b{sb}/
  

sb は「文境界」(Sentence Boundary) のことです。 これは自然言語の文のパースを助ける Unicode 特性です。 詳しくは \b{}, \b, \B{}, \B" in perlrebackslash を参照してください。

perl5220delta - perl v5.22.0 での変更点 - perldoc.jp

非捕捉正規表現フラグ

正規表現は、捕捉してグループ内で $1, $2 などを埋める機能を無効にする /n フラグに対応しました:

    "hello" =~ /(hi|hello)/n; # $1 is not set
  

これは全ての捕捉グループの前に?: を置くのと等価です。

さらなる情報については "n" in perlre を参照してください。 修飾子 (perlre - Perl の正規表現 - perldoc.jp)

New \b boundaries in regular expressions

perlrebackslash - Perl 正規表現逆スラッシュシーケンスとエスケープ - perldoc.jp

  \b{}, \b, \B{}, \B

v5.22 から利用可能である \b{...} は、 中かっこの中で指定された境界タイプに関する Unicode の規則を基にして、 境界 (二つの文字の間、 文字列の最初の文字の前、文字列の最後の文字の後のいずれか) にマッチングします。 境界タイプは数段落後に述べます。 \B{...} は、同じ種類の \b{...} がマッチングしない全ての文字間に マッチングします。

\b の直後に "{" が引き続かない場合は、単語文字 (\w で マッチングするもの) と非単語文字 (\W) の境界にマッチングします; \B の直後に "{" が引き続かない場合は、\b が マッチングしない任意の文字間にマッチングします。 よりよい自然言語テキストの単語マッチングのためには、 後述の "\b{wb}" を参照してください。

\b と \B は、ソース文字列の先頭の前と末尾の後ろに非単語文字があると 仮定します; 従って \b は、 ソース文字列が単語文字で始まっている(または 終わっている)場合はソース文字列の先頭(または末尾)にマッチングします。 さもなければ、\B がマッチングします。

\b=head\d\b のようなものを使って行頭にマッチングすると 仮定しないでください。 これはできません; なぜなら非単語 "=" の前に境界があり、 直前に単語文字が なければならないからです。 全ての単なる \b および \B の境界決定は単語文字のみを探し、 非単語文字や 文字列の末尾は探しません。 \b と \B がどのように動作するかは以下のように同等化することで 理解の助けになるでしょう:

  \b  really means    (?:(?<=\w)(?!\w)|(?<!\w)(?=\w))
  \B  really means    (?:(?<=\w)(?=\w)|(?<!\w)(?!\w))

一方、\b{...} と \B{...} は、境界の種類に依存して、 行の先頭と末尾にマッチングしたりしなかったりします。 これらは http://www.unicode.org/reports/tr14/ と http://www.unicode.org/reports/tr29/ で定義されている Unicode のデフォルト境界を実装しています。 境界タイプは:

  \b{gcb} or \b{g}

これは Unicode の「書記素境界」("Grapheme Cluster Boundary") に マッチングします。 (実際には Perl は改良された「拡張書記素」("extended grapheme cluster") を 常に使います。) これらは "\X" で後述します。 実際のところ、\X は同じ機能を使うためのもう一つの方法です。 これは /.+?\b{gcb}/ と等価です。 状況に応じて使いやすい方を使ってください。

  \b{lb}

これはデフォルトの Unicode Line Breaking Algorithm (http://www.unicode.org/reports/tr14/) に従ってマッチングしますが、 数値表現をより良く扱うために、 (Example 7 of revision 35) 文書でカスタマイズされています。

これは多くの用途に使えますが、CPAN で利用可能な Unicode::LineBreak モジュールは、 カスタマイズを含むより多くの機能が利用可能です。

  \b{sb}

これは Unicode の「文境界」("Sentence Boundary") にマッチングします。 これは自然言語文をパースする助けとなります。 この結果はよいけれども完璧ではないものです。 例えば、これは "Mr. Smith" を二つの文と考えます。 さらなる詳細は http://www.unicode.org/reports/tr29/ にあります。 また、(フォームフィードと垂直タブを除く) "\R" にマッチングするものも 行境界と考えることに注意してください。 \b{sb} は、表示用に自動的に行をラッピングするワードプロセッサ用に デザインされたテキストに対して動作しますが、 ハードコーディングされた行境界は基本的にテキストブロック(実際には段落)の 終わりであり、従って分の終わりと考えられます。 \b{sb} は、あなたが今読んでいる文書のソーステキストのような、 組み込みの改行を含むテキストに対しては上手く動作しません。 このようなテキストについては、文境界を探す前に行セパレータを取り除く前処理が必要です。 これは Unicode 標準のバグであると考える人々もいて、 この振る舞いは将来の Perl バージョンで変更されるかもしれません。

  \b{wb}

これは Unicode の「単語境界」("Word Boundary") にマッチングしますが、 Perl に合わせて修正しています。 これは自然言語処理において単なる \b (中かっこなし) よりも良い (しかし完璧ではない)結果を返します。 例えば、アポストロフィは単語の途中にあってもよいけれども かっこはあってはならないということを理解します (後述する例を参照してください)。 さらなる詳細は http://www.unicode.org/reports/tr29/ にあります。

単語境界について、現在の Unicode の定義としては全ての空白文字の間に マッチングします。 Perl は 5.24 からこれを調整し、 単なる \b が常に機能するように、 一般的に空白の範囲を分割しないようにします。 これにより \b{wb} を \b の置き換えとして使えるだけでなく、 自然言語処理では一般的により良い結果になります。 (この調整の例外は、 ある範囲の空白の直後に U+0303, COMBINING TILDE のようなものが 引き続いている場合です。 その範囲の最後の空白文字が垂直空白文字の場合、結合文字に付くように 分割されます。 正確に言うと、垂直スペースで終わる空白の範囲の直後に Word Boundary 特性の値が "Extend", "Format", "ZWJ" の文字が引き続く場合、 最後の垂直スペース文字とその範囲の残りの間の境界は \b{wb} に マッチングします。 それ以外の場合は、 二つの空白文字の間の境界は\B{wb} にマッチングします。)

これらの Unicode 境界を使う場合、 後のバージョンの Unicode 標準を含む将来のバージョンの Perl では、 コードを書いた時点と正確に同じように動作しないかもしれないという リスクを取ることになるということを認識することは重要です。 これらの規則は安定しているとは考えられておらず、標準の他の部分よりも 変更される可能性がより高いです。 Unicode は自分の意思でこれらを変更する権利を保持していて、 Perl はその実装を Unicode の新しい規則に更新する権利を保持しています。 過去には、以前の全ての文字と異なる性格を持つ新しい文字を標準に追加するために、 変更が行われたことがあります。 それらを扱うために新しい規則が策定されました。 これらは後方互換性問題は発生させないはずです。 しかし、Unicode Technical Committee が何らかの理由で変更が正当化されると考えたことによって、 既存の文字の扱いが変更されたことがあります。 これはバグを修正するためかもしれませんし、 彼らが新しい規則によってより良い結果を得られると考えるからかもしれません。

また、これらはデフォルトの境界定義であり、実装は特定の目的やロケールのために結果を調整する必要があることがあるということを 認識することが重要です。 例えば、日本語やタイ語のような一部の言語では、単語境界の正確な決定には 辞書検索が必要です。

Perl 5.24.0 時点での変更点のまとめ

New \b{lb} boundary in regular expressions

Perl 5.26.0 時点での変更点のまとめ

(あとで書く)

2021年4月追記

Unicode の Script property の扱いに変更があり、それが \p{Hiragana} のマッチする範囲に影響した。 参考: Perlで\p{Hiragana}とかが記号にマッチする問題 - Qiita

Use of \p{script} uses the improved Script_Extensions property

Unicode 6.0 introduced an improved form of the Script (sc) property, and called it Script_Extensions (scx). Perl now uses this improved version when a property is specified as just \p{script}. This should make programs more accurate when determining if a character is used in a given script, but there is a slight chance of breakage for programs that very specifically needed the old behavior. The meaning of compound forms, like \p{sc=script} are unchanged. See "Scripts" in perlunicode.

(\p{script} を使うと改良された Script_Extensions 特性を使います)

Unicode 6.0 は Script (sc) 特性の改良された型式を導入しました; これは Script_Extensions (scx) と呼ばれます。 Perl は、特性を単に \p{script} として指定された場合はこの 改良版を使うようになりました。 これにより、ある文字が特定の用字で使われているかを判定するプログラムが より正確になるはずですが、 特に具体的に古い振る舞いが必要なプログラムを 壊す可能性が僅かにあります。 \p{sc=script} のような複合形式の意味は変わりません。 "Scripts" in perlunicode を参照してください。

Perl 5.28.0 時点での変更点のまとめ

Script Runs 混合 Unicode 用字を検出可能になりました

ある文字列の中で Cyrillic と Latin のような用字が混ざっているようなものは、 しばしばスプーフィング攻撃のサインとなります。 新しい正規表現構文はこれらを簡単に検出できるようになります。 例えば、次のようにすると:

    qr/(*script_run: \d+ \b )/x
  

マッチングする数字は 10 ある中の同じ集合の中のものになります。 見た目と異なる値を持つ異なった用字からの数字に見えるものには マッチングしません。

または:

    qr/(*sr: \b \w+ \b )/x
  

このようにすると全ての文字が同じ用字であることを確実にできます。

また、(?>...) (あるいは (*atomic:...)) で用字を結合することもできます。

このように書く代わりに:

    (*sr:(?<...))
  

次のようにできます:

    (*asr:...)
    # or
    (*atomic_script_run:...)
  

これは実験的と考えられるので、これらを使うと (オフにしない限り) experimental::script_run カテゴリの警告が発生します。

Alpabetic assertions 実験的に、正規表現アサートの英字の別名が利用可能になりました

特定のパターンアサートの書き方を覚えるのが難しい場合、 英文字の同義語が使えるようになりました.

 CURRENT                NEW SYNONYMS
 ------                 ------------
(?=...)        (*pla:...) or (*positive_lookahead:...)
(?!...)        (*nla:...) or (*negative_lookahead:...)
(?<=...)        (*plb:...) or (*positive_lookbehind:...)
(?<!...)        (*nlb:...) or (*negative_lookbehind:...)
 (?>...)        (*atomic:...)

これは実験的と考えられているので、これらを使うと(オフにしない限り) experimental::alpha_assertions カテゴリの警告が発生します。

追記: 5.32.0で実験的機能ではなくなりました(ので、使っても警告は出ません)。

Perl 5.30.0 時点でのまとめ

Perl v5.30 lets you match more with the general quantifier | The Effective Perler

    Things to Remember
  

The general quantifier {,} has a maximum number of repetitions, even though that is probably more than you ever need. The + should be equivalent, but can match much more. v5.30 will increase the limit for {,}. If you've been working around that limitation, I want to hear about what you are doing.

Unicode 特性値指定のワイルドカードに部分的に対応しました

正規表現パターン中で次のようなことができるようになりました:

    qr! \p{nv= /(?x) \A [0-5] \z / }!
  

これは数値が 0 から 5 であるすべての Unicode 符号位置にマッチングします。 従って、これはタイ語数字やベンガル語数字で 0, 1, 2, 3, 4, 5 を意味する ものにマッチングします。

これは Unicode Consortium が提案している正規表現機能を実装するための さらなる一歩となります。

ほとんどの特性に対応していて、残りは 5.32 に計画されています。 詳細は "Wildcards in Property Values" in perlunicode にあります。

Perl 5.32.0 時点でのまとめ

perl5320delta - perl v5.32.0 での変更点 - perldoc.jp

    New Unicode properties Identifier_Status and Identifier_Type supported
    (新しい Unicode 特性 Identifier_Status と Identifier_Type に対応)
  

Unicode は正規表現要件の見直し作業中です: https://www.unicode.org/draft/reports/tr18/tr18.html この一環として、厳密な UCD (Unicode character database) の一部ではない、 より多くの特性を露出させるように求めています。 これら二つはセキュリティ上の理由で入力を検査するために使われています。 これらの使用法の詳細は https://www.unicode.org/reports/tr39/proposed.html にあります。

    It is now possible to write qr/\p{Name=...}/, or qr!\p{na=/(SMILING|GRINNING) FACE/}!
    (qr/\p{Name=...}/ や qr!\p{na=/(SMILING|GRINNING) FACE/}! と書けるようになりました)
  

\N{...} の代替策として、Unicode Name 特性が正規表現パターン中で アクセス可能になりました。 二つの手法の比較は "Comparison of \N{...} and \p{name=...}" in perlunicode にあります。

前述の 2 番目の例は、この特性でワイルドカード部分パターンも使えることを 示しています。 "Wildcards in Property Values" in perlunicode を参照してください。

    アルファアサートはもはや実験的ではなくなりました
  

"(*pla:pattern)" in perlre, "(*plb:pattern)" in perlre, "(*nla:pattern)" in perlre>, "(*nlb:pattern)" in perlre を参照してください。 これらの使用はもはや警告を出力しません; 警告カテゴリ experimental::alpha_assertions を無効にする既存のコードは 何の変更の必要もなく動き続けます。 このカテゴリを有効にしても何も起きません。

    用字並びはもはや実験的ではなくなりました
  

Script Runs" in perlre を参照してください。 これらの使用はもはや警告を出力しません; 警告カテゴリ experimental::script_run を無効にする既存のコードは 何の変更の必要もなく動き続けます。 このカテゴリを有効にしても何も起きません。

    コンパイルされたパターンは最適化される前にダンプされるようになりました
  

これは主に正規表現コンパイラの中のバグを見つけ出すのに有用です。 このダンプは -DDEBUGGING perl でコマンドラインに -Drv を指定するか; パターンが use re qw(Debug DUMP_PRE_OPTIMIZE) または use re qw(Debug COMPILE EXTRA) のスコープの下でコンパイルされた場合は 全ての perl で発生します (2 番目以外の全ての場合は他の情報も表示されます。)

perl5320delta - what is new for perl v5.32.0 - Perldoc Browser

    Alpha assertions are no longer experimental
  

See "(*pla:pattern)" in perlre, "(*plb:pattern)" in perlre, "(*nla:pattern)" in perlre, and "(*nlb:pattern)" in perlre. Use of these no longer generates a warning; existing code that disables the warning category experimental::alpha_assertions will continue to work without any changes needed. Enabling the category has no effect.

    Script runs are no longer experimental
  

See "Script Runs" in perlre. Use of these no longer generates a warning; existing code that disables the warning category experimental::script_run will continue to work without any changes needed. Enabling the category has no effect.

Perl 5.32.1 時点でのまとめ

perldelta - what is new for perl v5.32.1 - Perldoc Browser

    Changes to Existing Diagnostics
  
    \K not permitted in lookahead/lookbehind in regex; marked by <-- HERE in m/%s/
    This error was incorrectly produced in some cases involving nested lookarounds. This has been fixed.
    [GH #18123]
  
Perl 5.34.0 時点でのまとめ

perldelta - what is new for perl v5.34.0 - Perldoc Browser (日本語訳は perl5340delta - perl v5.34.0 での変更点 - perldoc.jp にあります)より

qr/{,n}/ is now accepted

An empty lower bound is now accepted for regular expression quantifiers, like {,3}.

perldelta - what is new for perl v5.34.0 - Perldoc Browser より

Blanks freely allowed within but adjacent to curly braces

(in double-quotish contexts and regular expression patterns)

This means you can write things like \x{ FFFC } if you like. This applies to all such constructs, namely \b{}, \g{}, \k{}, \N{}, \o{}, and \x{}; as well as the regular expression quantifier {m,n}. \p{} and \P{} retain their already-existing, even looser, rules mandated by the Unicode standard (see "Properties accessible through \p{} and \P{}" in perluniprops).

This ability is in effect regardless of the presence of the /x regular expression pattern modifier.

Additionally, the comma in a regular expression braced quantifier may have blanks (tabs or spaces) before and/or after the comma, like qr/a{ 5, 7 }/.

Perl 5.36.0 時点でのまとめ

perldelta - what is new for perl v5.36.0 - metacpan.org 日本語訳は perl5360delta - perl v5.36.0 での変更点 - perldoc.jp

regex sets are no longer considered experimental

Prior to this release, the regex sets feature (officially named "Extended Bracketed Character Classes") was considered experimental. Introduced in Perl version 5.18.0, and modified several times since, this is now considered a stable language feature and its use no longer prints a warning. See "Extended Bracketed Character Classes" in perlrecharclass.

perldelta - what is new for perl v5.36.0 - metacpan.org

Variable length lookbehind is mostly no longer considered experimental

Prior to this release, any form of variable length lookbehind was considered experimental. With this release the experimental status has been reduced to cover only lookbehind that contains capturing parenthesis. This is because it is not clear if

"aaz"=~/(?=z)(?<=(a|aa))/

should match and leave $1 equaling "a" or "aa". Currently it will match the longest possible alternative, "aa". While we are confident that the overall construct will now match only when it should, we are not confident that we will keep the current "longest match" behavior.


Perl 6で使用できる正規表現演算子

Rakuで使用できる正規表現演算子

perl 6 の Rules について (あとで書く)

Pythonで使用できる正規表現演算子

本稿修正時のPyhtonのバージョン 3.6.4
6.2. re — Regular expression operations — Python 3.6.4 documentation

正規表現コンパイル時に指定できるオプションもあります。 Python 2.4 から以下のものが使えるようです。 Perlとは異なり conditionの部分には名前つきパターンのグループ名も可能なようですが、 先読みや戻り読み等の指定はできないようです。

2.4以降で追加/変更されたあれこれ

    (?(id/name)yes-pattern|no-pattern)
  

Will try to match with yes-pattern if the group with given id or name exists, and with no-pattern if it doesn’t. no-pattern is optional and can be omitted. For example, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) is a poor email matching pattern, which will match with '<user@host.com>' as well as 'user@host.com', but not with '<user@host.com'.

    Changed in version 3.3: The '\u' and '\U' escape sequences have been added.
    Changed in version 3.6: Unknown escapes consisting of '\' and an ASCII letter now are errors.
  
    Changed in version 3.5: Added support for group references of fixed length.
  

New in 3.6

    (?imsx-imsx:...)
  

(Zero or more letters from the set 'i', 'm', 's', 'x', optionally followed by '-' followed by one or more letters from the same set.) The letters set or removes the corresponding flags: re.I (ignore case), re.M (multi-line), re.S (dot matches all), and re.X (verbose), for the part of the expression. (The flags are described in Module Contents.)

いつの時点で追加されたものかわかりません(調べていない)が、3.9.1の時点で以下の記述がありました。

Unicode Technical Standard #18 にあるような集合の入れ子や集合操作が将来追加される可能性があります。 これは構文を変化させるもので、この変化を容易にするために、さしあたって曖昧な事例には FutureWarning が送出されます。 これはリテラル '[' で始まる集合や、リテラル文字の連続 '--' 、 '&&' 、 '~~' および '||' を含む集合を含みます。 警告を避けるにはバックスラッシュでエスケープしてください。

3.7だったようです。 What's New In Python 3.7 — Python 3.7.9 ドキュメント

FutureWarning is now emitted if a regular expression contains character set constructs that will change semantically in the future, such as nested sets and set operations. (Contributed by Serhiy Storchaka in bpo-30349.)

regex

2021年10月現在、新しい正規表現モジュールregex (regex · PyPI) の開発が進められているようです。 reモジュール以前に使われていた正規表現モジュールもregexという名前だったはずですが、 置き換えられてからかなりの時間が経っているので(知らない人も多いでしょう)、 問題ないということなのでしょうか。

This regex implementation is backwards-compatible with the standard 're' module, but offers additional functionality.

Ruby で使用できる正規表現演算子

本稿修正時のRubyのバージョン 2.4.1 (1.9以前の記述は削除しました)。
2022年1月3日時点の最新バージョン 3.1.0

詳しいドキュメントは 正規表現 (Ruby 2.4.0) にあります。

Ruby 2.0.0 より、使用する正規表現ライブラリがそれまで使っていた鬼車 (kkos/oniguruma: regular expression library) から、その派生である鬼雲 (Onigmo/README.ja at master · k-takata/Onigmo) に変更されました。

Unicode プロパティ
使用できるプロパティなどは Onigmo/UnicodeProps.txt at master · k-takata/Onigmo を参照してください。

部分式呼び出し
詳しくは 正規表現 (Ruby 2.4.0) を参照してください。

    キャプチャ & グループ化

    (pat) 通常のキャプチャ&グループ化
    \1, \2, ... キャプチャを参照
    \k<1>, \k<2>, ... キャプチャを参照
    \k'1', \k'2', ... キャプチャを参照
    \k<-1>, \k<-2>, ... キャプチャを参照(相対後方参照)
    \k'-1', \k'-2', ... キャプチャを参照(相対後方参照)
    (?<name>pat) (?'name'pat) 名前付きキャプチャ
    \k<name> 名前付きキャプチャを参照
    \k'name' 名前付きキャプチャを参照
    (?:pat) キャプチャしないグループ化
    (?>pat) アトミックグループ化

    部分式呼び出し

    \g<name> 名前指定呼出し
    \g'name' 名前指定呼出し
    \g<n> 番号指定呼出し (n >= 1)
    \g'n' 番号指定呼出し (n >= 1)
    \g<0> パターン全体の再帰呼び出し
    \g'0' パターン全体の再帰呼び出し
    \g<-n> 相対番号指定呼出し (n >= 1)
    \g'-n' 相対番号指定呼出し (n >= 1)
    \g<+n> 相対番号指定呼出し (n >= 1)
    \g'+n' 相対番号指定呼出し (n >= 1)
    \k<n+level> (n >= 1) ネストレベル付き後方参照
    \k<n-level> (n >= 1) ネストレベル付き後方参照
    \k'n+level' (n >= 1) ネストレベル付き後方参照
    \k'n-level' (n >= 1) ネストレベル付き後方参照
    \k<-n+level> (n >= 1) ネストレベル付き後方参照
    \k<-n-level> (n >= 1) ネストレベル付き後方参照
    \k'-n+level' (n >= 1) ネストレベル付き後方参照
    \k'-n-level' (n >= 1) ネストレベル付き後方参照
    \k<name+level> ネストレベル付き後方参照
    \k<name-level> ネストレベル付き後方参照
    \k'name+level' ネストレベル付き後方参照
    \k'name-level' ネストレベル付き後方参照
  

Ruby 2.4.1 で 非包含オペレーターが追加されました。

gawk (3.0以降)で使用できる正規表現演算子

2020年12月20日時点での最新バージョン 5.1.0 2022年1月3日時点の最新バージョン 5.1.1

特記事項:
gawk 3.0.0以降、それまでのバージョンのものとは異なり "." が 改行にもマッチするように仕様が変更されました。 gawk 3.0に関しては http://www.kt.rim.or.jp/~kbk/gawk-30/index.html にマニュアルの邦訳を置いています(4以降のドキュメントを訳す元気は今のところない)。

2017年12月追記:
gawk で 4.0 へのバージョンアップ時に以下の変更あり (1.は正規表現には関係ありません)。

    Changes from 3.1.8 to 4.0.0
    ---------------------------
    1. The special files /dev/pid, /dev/ppid, /dev/pgrpid and /dev/user are
    now completely gone. Use PROCINFO instead.

    2. The POSIX 2008 behavior for `sub' and `gsub' are now the default.
    THIS CHANGES BEHAVIOR!!!!

    3. The \s and \S escape sequences are now recognized in regular expressions.
  

Tcl 8.2.3(以降)で使用できる正規表現演算子

8.1になってPerl5ライクな正規表現が使えるようになっています。

メタ構文。 (?bc)regexp のように使います。複数同時に指定することが可能です。

正規表現が以下のシーケンスで始まっていた場合、解釈に違いが出ます。

詳しくは re_syntax をどうぞ。 日本語のドキュメントは Tcl 8.4.1 マニュアル ビルトインコマンドリファレンス re_syntax にあります。

PCRE(ver 4.x)で使用できる正規表現演算子

PCRE - Perl Compatible Regular Expressions はPerl 5.8にほぼ準じた正規表現が使用可能で、 いろいろな処理系でライブラリとして使われています。

2022年1月10日時点の最新バージョン 10.39
Releases · PhilipHazel/pcre2

お断り:
PCREは2015年にPCRE2がリリースされ ([pcre-dev] PCRE2 is released)、 旧来のものはメンテナンスモードとなりました。 2022年1月10日時点でのPCREの最新版は10.39、 PCRE1(旧版)は8.45となっています。 そして長いこと放置しているので以下にある情報は古くなっています。

PCREのPOSIXキャラクタクラス指定では ^を前置した否定形も使用することができます (ex: [^:digit:])。

PCRE 5.0ではUnicodeプロパティが使えます(コンパイル時に有効に設定してビルドした場合)。 その場合に使用できるプロパティは以下の表の通りです。使用する場合、 \p{Ll}\P{Lu}のように記述します (\pは指定するプロパティに含まれるキャラクタ、 \Pは指定するプロパティに含まれないキャラクタにマッチします)。 Perlと同様、\p{^Lu}のような否定形の指定も可能です。 \p,\Pに続くプロパティ指定が一文字である場合ブレースは省略可能です。 また、\Xというエスケープシーケンスも使えます。 これは (?>\PM\pM*) と等価です(アクセントつきの文字などの指定です)。

PCRE 5.0で使えるUnicodeプロパティ
表記 意味
C Other
Cc Control
Cf Format
Cn Unassigned
Co Private use
Cs Surrogate
L 文字
Ll 小文字
Lm Modifier letter
Lo Other letter
Lt Title case letter
Lu 大文字
M Mark
Mc Spacing mark
Me Enclosing mark
Mn Non-spacing mark
N 数字
Nd 十進数字
Nl Letter number
No Other number
P Punctuation
Pc Connector punctuation
Pd Dash punctuation
Pe Close punctuation
Pf Final punctuation
Pi Initial punctuation
Po Other punctuation
Ps Open punctuation
S Symbol
Sc Currency symbol
Sk Modifier symbol
Sm Mathematical symbol
So Other symbol
Z Separator
Zl Line separator
Zp Paragraph separator
Zs Space separator

PHP で使用できる正規表現演算子

POSIX regex (ereg_* で使える正規表現)は deprecated となっています。 また、mb_ereg の扱いがどうなっているのかはよくわかりません (deprecated ではないようですが) (何か変わったっぽい?(未確認)) マルチバイト対応PHPには三種類の正規表現ルーチンがありますが、 ここではマルチバイト文字対応のmb_eregにしぼって列挙します。 Rubyの正規表現ルーチンを使っているので、Rubyのものと基本的には同じです。 preg_*関数群はPCREを使っているので使える正規表現はPCRE に準じます。ereg_*で使える正規表現はPOSIX ERE[[:<:]][[:>:]] のようです(Henry Spencer作のライブラリらしい)。

The POSIX functions are deprecated. Instead of the "ereg" collection you want to use something from the PCRE world. http://www.php.net/manual/en/book.pcre.php

PHP本体のバージョンと使用しているPCREのバージョンとの対応は PHP: インストール手順 - Manual の「バンドルされている PCRE ライブラリの更新履歴」を参照のこと。


.NET Frameworkで使用できる正規表現

たぶん 2.0辺りのもの。 そこから2017年12月31日現在の最新(4.7.1)までに追加・変更がどの程度あったのかは未調査。

特記事項 → .NETの正規表現に関する特記事項

コンパイル時に指定できるオプションもあります。 詳しくは.NET Framework の正規表現を参照してください。


Javaで使用できる正規表現

特記事項 → Javaの正規表現に関する特記事項

コンパイル時に指定できるオプションもあります。 詳しくは Pattern (Java2 プラットフォーム SE v1.4.0 Pattern (Java Platform SE 8 ) を参照してください。


JavaScript

Javascriptの正規表現について

こちらのサイトへどうぞ。


POSIX 1003.2

POSIX 1003.2での正規表現について

POSIX 1003.2では二種類の正規表現、 Basic Regular Expression(以下BRE)と Extended Reuglar Exression(以下ERE)が定められています。 BREを使用するユーティリティには、ed, ex, vi, more, sed, grepなどが、 EREを使用するユーティリティには awk, egrep などがあります。 Regular Expressoions POSIX 1003.2 regular expressionsに説明があります。

BRE で使える正規表現演算子(メタキャラクタ)は以下の通りです。

EREで使える正規表現演算子(メタキャラクタ)は以下の通りです。


正規表現演算子

各正規表現演算子の説明

.

任意のキャラクタ一文字とマッチします。 処理系やオプション指定によってこれが改行にマッチするものとしないものとがあります。 POSIX 1003.2では改行にもマッチするように規定されているようです。

幾つかの処理系でのオプション指定をまとめました →

*

演算子の直前に置かれている部分正規表現の可能な限り大きい繰り返しにマッチします。 繰り返しの回数は0回でもかまいません。例を挙げると、

        fo*
    

は、foにもfooにもマッチしますし、f(oが一個もない)にもマッチします。 一般的には

        (foo)*
    

のように繰り返しの対象となるものは部分正規表現でも受け付けられますが、 処理系によっては文字の繰り返ししか認めていないものもあります。

*?

*と同様ですが、マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります)に行われる点が異なります。 (参照: “ものぐさなマッチングとは”)

+
\+

*と似ていますが、直前にある部分正規表現の一回以上の繰り返しにマッチします。 つまり、 wh+y という正規表現は、whywhhhyにはマッチしますが、 *とは違ってwyとはマッチしません。 \+は、GNU grepやGNU sedで用いられるこれと等価な演算子です。 これは他の処理系では使えないでしょう。

+?

+と同様ですが、マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります) に行われる点が異なります。 (参照: “ものぐさなマッチングとは”)

?
\?

直前にある部分正規表現、もしくは空文字列にマッチします。 \?は、GNU grepやGNU sedで用いられるこれと等価な演算子です。 これは他の処理系では使えないでしょう。

??

\?と同様ですが、 マッチングがものぐさ (lazy。non-greedy(慎ましやか)などの表現が使われることもあります)に行われる点が 異なります。 (参照: “ものぐさなマッチングとは”)

|
\|

これら二つの演算子は、選択を行なうためのものです。 演算子の左右に置かれた部分正規表現のいずれかにマッチします。 たとえば^X|0 は先頭にXがある文字列か、 0を含む文字列(先頭以外にあってもよい)かのいずれかにマッチします (^|はどちらも正規表現演算子ですが、 その優先順位は^の方が上のため、このような解釈になります)。 \|は、GNU grepやGNU sedで用いられる等価な演算子です。 これは他の処理系では使えないでしょう。

[char-list]

[]の中に置かれた文字のいずれかにマッチします。 これはキャラクタクラスなどと呼ばれます。 [ABC]という指定は、A, B, Cのいずれかにマッチします。 連続したキャラクタ群を指定する場合、 その群の先頭と終端を-で繋いだ形で指定することができます。 たとえば、[ABCDEFG]と(localeにもよりますが一般的には)[A-G]は等価な指定です。

多くの場合、ここでの順序はlocaleごとに定められた順序に従います。 localeによっては[a-z]に大文字の大部分が含まれたりする場合があるので注意が必要です。 たとえば GNU/Linux の en_US localeでは、
a A b B c C d D ... x X y Y z Z という並びになります。

[の直後に^がきていた場合には意味が逆になり、指定したキャラクタ群の補集合、 つまり[]内に置かれた文字以外の文字にマッチするということになります。 たとえば[^ABC]という正規表現は A, B, C 以外のキャラクタにマッチします。 範囲指定の終端と始点を共有する[a-c-e]のような指定をしたときの動作は未定義です。

キャラクタクラスの中では多くのメタキャラクタがその意味を失います。 特に、伝統的なegrepでは、[]の中では\によるエスケープも効きません (\自体もその特殊な意味を失ってしまう)。 そういった場合に]^-といった []内で特殊な意味を持つキャラクタをクラスに含めたいときには[]^-]のように記述します。 つまり、^[の直後以外に、 ][の直後 (補集合を指定しているときには^の直後)に置き、 -はリストの最後に置くというやり方を使います。

最近の処理系では\によるエスケープや\を使ったメタキャラクタ(\wや\sなど)が有効なものが多いようです。 むしろ鬼車などでは、[-] をキャラクタクラスに含めるときはそれらをエスケープすることが推奨されています。

鬼車やJavaなどでは、キャラクタクラスの集合演算が可能です。詳しくは 鬼車正規表現の 文字集合の項を参照してください。

よくある勘違い
[^foo]bar という正規表現は、「fooではない文字列に続いてbarという文字列が続くもの」 ではありません。 これは「fでもoでもない文字に続いてbarという文字列が続いたもの」です。 []で囲んだものが表しているのは文字列ではなく文字の集合(その中に含まれる/含まれない文字のどれか) だということに注意してください。

よくある勘違い その2
前述した通り、ブラケットに囲まれている中ではほとんどのメタキャラクタはその特殊な意味を失います。 したがって、[^(foo)]bar という正規表現もまた、 「fooではない文字列に続いてbarという文字列が続くもの」 ではありません。 これは「fでもoでも(でも)でもない文字に続いてbarという文字列が続いたもの」です。 []の内側では、文字列や(より小さな)正規表現要素をまとめるという カッコの特別な意味は失われてしまうということに注意してください。

ではどうすれば?
Perl 5拡張が使えるのなら、戻り読みで対処できます。

陥りやすい罠
[亜-腕][弌-熙] [亜-熙]といった正規表現はそれぞれ、 「JIS第一水準の範囲の漢字」や「JIS第二水準の漢字」、 「漢字」を表すものとして使われることが多かったものですが、 Unicodeをベースとしているシステム(5.8以降のuse encodingしたPerlなど)の場合は、 このような表記をしても期待通りの動作をすることはありません。 なぜなら、Unicode (or ISO 10646/JIS X 0221)では漢字の並べ方がこれまで用いられてきた規格 (JIS X 0208) のそれとは異なるためです。

(regexp)
\(regexp\)

()とで囲むことにより、 ある一部分の文字列や正規表現をひとまとめに扱うことができます。 たとえば(bang)+という正規表現は、 bangbangbangbangbangbangという文字列にマッチします。 bang+としたときとどのように違うかを確かめてみてください。

\(\)は、sed、grep、ed等 BREで使用される書き方で、 その働きは()と同じですがBREでは後方参照を行うための指定にもなります。 GNU grepの-Eオプション指定時では()も同様の働きをしますが、 POSIX 1003.2で規定されているEREでは後方参照が使えるという記述はありません。

{n,m}
{n,}
{n}
\{n\}
\{n,\}
\{n,m\}

m、nにはそれぞれ数値が入ります。 数字が nだけの場合はちょうどn回の繰り返しの指定になります。 {n,}という形の場合ではn回以上の繰り返しの指定、 {n,m}ではn回以上m回以下の繰り返しの指定となります。 たとえば{3,5}では(直前の正規表現の)3回から5回の繰り返しになります。 ですから、

      hel{3,5}o
    

helllo, hellllo, helllllo にマッチしますが、 helloにはマッチしません。 \{\}はsed、grep等で使用される書き方で、働きは{}と同じです。

繰り返しの回数の指定には処理系ごとに制限があります。 最も厳しい場合で255回程度が最大値となります。 あまり大きな数字は使えないと考えたほうが良いでしょう。 また、負の数を指定することは許されません。 最大値ですが、PerlやRuby1.8で32766、GNU grepやGNU sedで32767、PCREで65535あたりです (Pythonでは4294967295(32bitの無符号整数の最大値)まで可能?)。

{m,n}?
{n,}?
{n}?

{m,n}等と同様ですが、マッチングがものぐさ(non-greedy)に行われる点が異なります。

^

文字列の先頭にマッチします。たとえば^cryptcrypt にマッチしますが、 encryptにはマッチしません。 処理系やモードによっては文字列中の改行の直後(つまり行の始め)にもマッチします。

$

文字列の末尾にマッチします。たとえばgo$goとマッチしますが、 goldにはマッチしません。 処理系やモードによっては文字列中の改行の直前(つまり行の終わり)にもマッチします。 これは「アンカー」であり、改行を表す文字そのものにマッチするのではないということに注意してください。

\<
\m,[[:<:]]

“単語”の先頭にマッチします。 たとえば\<away awayにマッチしますが、 farawayにはマッチしません。

Tclでは\mまたは[[:<:]]を使います。

\>
\M,[[:>:]]

“単語”の末尾にマッチします。 ですから、gnu\>gnuにマッチしますが cygnusにはマッチしません。

Tclでは\Mまたは[[:>:]]を使います。

[:classname:]

POSIX1003.2では、 キャラクタクラス指定のときに名前によるキャラクタークラスの指定ができるようになりました。 現在決められているものとそれぞれの意味は以下のようになっています。 これらのほかに、そのときのlocaleによってlocale依存のキャラクタクラスが使える場合があります。

POSIXキャラクタクラス
クラス名 意味
[:alnum:] アルファベットと(十進)数字
[:alpha:] アルファベット
[:blank:] 空白文字(スペース、タブ等)
[:cntrl:] 制御文字
[:digit:] 十進数字
[:graph:] 印字可能かつ表示可能な文字(スペースは印字可能だが表示可能ではない)
[:lower:] アルファベットの小文字
[:print:] 印字可能なキャラクタ(=制御文字以外のキャラクタ)
[:punct:] 句読点(通常の文字、数字、制御文字、スペースのいずれでもないキャラクター)
[:space:] スペース、タブ、改ページ
[:upper:] アルファベットの大文字
[:xdigit:] 十六進数字

これらは実際に使用するときには[[:lower:]]のような形になります (ブラケットが二重になっていることに注意してください。 また、[A-F[:lower:]][[:punct:][:space:]]のような書き方も可能です)。 キャラクタークラスの名称は、Cライブラリ関数のisxxx (ここで、xxxには上記のキャラクタークラスの名称が入ります) で識別されるものと同じ集合を表します。 [^:alnum:]のような否定形を使える処理系もあります。

実際にこれらを使用したときの文字集合は、 利用した時点におけるlocaleに影響される可能性があるということに注意すべきです。

Perl(5.6以降)および PCRE には[:word:] (単語構成文字にマッチ)があります。

幾つかの文献に[:blank:]がGNU拡張であるという記述がありますが、 手元にあるPOSIX 1003.2のドキュメントには[:blank:]の項目が存在しています。

LC_CTYPEの設定に応じて任意のキャラクタクラスを認識するようにしても良いことになっています。

\w

“単語”を構成するキャラクタ、 つまり、文字と数字それにアンダースコアのいずれかにマッチします。 これは[[:alnum:]]と同じ意味になります。 [[:alnum:]] 同様、localeに影響される可能性に注意してください (処理系のバージョン、設定に依存するので詳細はここでは書きません)。

\W

“単語”を構成するキャラクタ以外のキャラクタのいずれかにマッチします。 これは[^[:alnum:]](使える場合は[[^:alnum:]]も)と同じ意味になります。 これもまたlocaleに影響される可能性に注意してください。

\b
\y

“単語”の先頭、あるいは末尾にマッチします。 言い換えれば“語の区切り”とマッチするということです。 たとえば\bball\bは前後に空白のある ball にはマッチしますが、 baseballにはマッチしません。

gawk 3.0以降では、 \bがバックスペースを表すエスケープシーケンスと衝突するため、 この演算子は\y となっています。 Tclでも\yを使います。

\B
\Y

“単語”の中にある空文字列にマッチします。 たとえば\Bgnu\Bcygnusにはマッチしますが gnuにはマッチしません。

一部の実装を除き、 a  (aの後に空白二つ)が \Bにマッチするようです(単語の境界にない空文字列にマッチ)。

Tclでは\Yを使用します。

\d

perl等で使用されるもので、[0-9]と同じ意味、つまり任意の十進数字とマッチします。 これについても locale に影響される可能性があります (たとえば 一、二、三 といった文字にもマッチしたりとか)。

\D

\dと似ていますが、その意味は[^0-9]、 つまり十進数字以外の任意の一文字とマッチします。

\s

「空白」一文字とマッチする正規表現演算子です。これもlocaleの影響に注意が必要です。 とくに Unicode でいう「空白」にはいろいろなものがあります。

\S

「空白以外」の一文字とマッチする正規表現演算子です。

\C

常に「1バイト」にマッチします。

\X

基本文字に続く任意個の合成文字で表されるUnicodeキャラクタにマッチします。

\A

^と似た働きをしますが、 大きな違いは^が文字列中に埋め込まれた改行の直後にもマッチする場合があるのに対して、 この演算子は常に文字列の先頭にのみマッチするという点です。

\Z

$と似ていますが、 $が文字列中に埋め込まれた改行の直前にもマッチすることがあるのに対して、 この演算子は基本的には文字列の末尾にのみマッチするという点が異なります。 ただし文字列の最後の文字が改行であるとき、 \Zは文字列の末尾だけでなく最後の改行の直前にもマッチします。 したがって

   foo\Z

   foo\n

(ここで\nは埋め込みの改行)にマッチしますが、

   foo\n\n

にはマッチしません。

\z

Perl 5.005で導入されたもので \Zと似ていますが、 \Zが文字列末尾の改行の直前にもマッチするのに対して この演算子は文字列の末尾にのみマッチするという点が異なります。

\G

文字列の先頭もしくは(グローバル指定時の)前のマッチが終了した位置にマッチします。

\`

バッファの先頭にマッチします。 ^は処理系やオプション指定によっては改行の直後にもマッチしますが、 この演算子はそういった場所にはマッチしません。

\'

バッファの末尾にマッチします。 $は処理系やオプション指定によっては改行の直前にもマッチしますが、 この演算子はそういった場所にはマッチしません。

\1 \2 \3 \4 \5 \6 \7 \8 \9

これらはそれに先行して現れた\(\)(または()) で囲まれた部分正規表現に実際にマッチしている文字列を表します。 \に続く数字は、正規表現全体の中でそれが現れた順番を示します。 たとえば\1は最初に現れた部分正規表現に対する参照であり、 \7であれば七番目に現れたものに対する参照です。 この指定は、Perl、Ruby、Tcl、PCREなどで九番目を越える指定が可能です。 ただし、対応する部分正規表現があることが条件になります。 また、数字部分が0で始まってはいけません。 これは8進数値指定との区別がつかないためです。

たとえば \(abc|123\)def\1という正規表現では、 \1abc123のいずれかになります。

曖昧さをなくすための表記を持っている処理系があります。 たとえばPythonでは \g<num>という表記が使えますし、 Perlではブレースを使って${1}のようにします。

\

\は厳密には正規表現演算子ではありません。 しかし上述した正規表現演算子を文字そのものとして扱いたいような場合に その前に\を置くことによって演算子の働きを抑制することができるので、 正規表現演算子の一つとして説明します。 たとえば\[[というキャラクタそのものを表すものとなり、 キャラクタクラスの始まりを示すものにはなりません。

[.string.]
[=char=]

[..]は collating symbol(照合シンボル)と呼ばれる演算子で、 [.と.]に挟まれたキャラクタ列を一つの照合要素とみなすように指定します。 たとえば [.ch.]+ch の(任意の組み合わせの)繰り返しではなく、 chchのような繰り返しにマッチします。 一方[==]は equivalence class(等価クラス)と呼ばれるもので、 [=と=]の間にあるキャラクタと“等価”なキャラクタにマッチします。 たとえば[=e=]として、 eに加えて è、 é、 ê、 ë といったものも含まれるという指定ができます。

現状では、Perl、PCREのように認識はするが動作はしないという実装が主流のようです(Tclでは使える?)。

glibcでもコードとしては入っているようです。どのように使えるのかは確かめていません。

(?# text)

正規表現中に置くコメントです。括弧内にあるものはマッチングには関係しません。

拡張モード時には#から行末までがコメントになります。

(?imsx-imsx:pattern)
(?imsx-imsx)

正規表現のオプションを指定します。 これを使うことによってオプションを以降の正規表現に部分的に適用することが可能となります。 i,s,m,xはそれぞれ独立に使用できます。 オプション指定の文字に-が先行している場合にはそのオプションを打ち消す意味になります。 また、(?ms:)のようにオプション指定文字に続いて :が置かれている場合にはそのかっこに囲まれた範囲にオプション指定による影響が限定されます (このオプション指定が存在していない処理系もあります。詳細は処理系のドキュメントを参照してください)。 後者の書き方では以降のすべてに影響が及びます。

Rubyにはsオプションはありません。またmオプション指定時は改行が'.'にマッチするようになります。

i,s,m,xのそれぞれの意味は以下のとおりです。 シングルラインモードおよびマルチラインモードについての詳細はそれぞれの処理系のドキュメントを参照してください。

正規表現修飾子の意味
修飾子 意味
i 大小文字の違いを無視する
s シングルラインモードにする(.が改行にマッチする)
m マルチラインモードにする(^と$が改行の直前直後にマッチ)
x 拡張表記を許可する

Pythonには、locale依存を有効にするL修飾子と \w, \W, \b, \B の意味をUnicode のキャラクタプロパティに基づいたものにするu修飾子があります。

PCREには通常のマッチとものぐさマッチの指定とを逆転する(?U)オプションと、 PCRE_EXTRAモードを有効にする(?X)オプションがあります。 PCRE_EXTRAモードでは、定義されていないバックスラッシュシーケンスがエラーになります。

Perl ではバージョンが進むごとに修飾子が追加されています。詳しくは perlre - Perl の正規表現 - perldoc.jp 中の perlre - Perl の正規表現 - perldoc.jpperlre - Perl の正規表現 - perldoc.jp を参照してください。

5.14 から利用可能な /d, /u, /a, /l は文字集合修飾子と呼ばれます; これらは正規表現で使われる文字集合の意味論に影響を与えます。

      /l 
    

文字集合をパターンマッチングの実行時に有効な ロケール(Locale)に設定します。

      /u 
    

文字集合を Unicode に設定します。

      /a 
    

文字コードを Unicode に設定しますが、 ASCII セーフなマッチングのためにいくつかの制限を加えます。

      /d 
    

この修飾子は、以下のように Unicode の規則が使われる場合を除いてプラットフォームの「デフォルトの」 (Default) ネイティブな規則を使うことを意味します:

      ターゲット文字列が UTF-8 でエンコードされている; または
      パターンが UTF-8 でエンコードされている; または
      パターンが、(\x{100} のような形で)255 を超える符号位置に明示的に 言及している; または
      パターンが Unicode 名 (\N{...}) を使っている; または
      パターンが Unicode 特性 (\p{...}) を使っている; または
      パターンが "(?[ ])" を使っている
    

Pythonで使用できる正規表現修飾子は下表のとおりです。

Pythonの正規表現修飾子の意味
修飾子 対応するオプション 意味
i IGNORECASE (I) 大小文字の違いを無視する
m MULTILINE (M) マルチラインモードにする(^と$がそれぞれ改行の直前や直後にマッチするようになる)
s DOTALL (S) .が改行文字にマッチするようにする
x VERBOSE (X) 拡張表記を許可する
u UNICODE (U) \w \W \b \BがUnicodeの英数定義に従う
l LOCALE (L) \w \W \b \Bがカレントのlocaleでの英数定義に従う

Rubyで使用できる正規表現修飾子は下表のとおりです。

Rubyの正規表現修飾子の意味
修飾子 対応するオプション 意味
i Regexp::IGNORECASE 大小文字の違いを無視する
m Regexp::MULTILINE マルチラインモードにする(^と$がそれぞれ改行の直前や直後にマッチするようになる)
x Regexp::EXTENDED 拡張表記を許可する

.NET Frameworkで使用できる正規表現修飾子は下表の通りです。

.NETの正規表現修飾子の意味
修飾子対応するオプション 意味
i RegexOptions.IgnoreCase 大小文字の違いを無視する
s RegexOptions.Singleline シングルラインモードにする(.が改行にマッチするようになる)
mRegexOptions.Multiline マルチラインモードにする (^$がそれぞれ改行の直前や直後にマッチするようになる)
n RegexOptions.ExplicitCapture (?<name>...) で陽に名前付けまたは番号付けしたグループだけを有効なキャプチャにするように指定する。
x RegexOptions.IgnorePatternWhitespace 拡張表記を許可する

Javaのjava.util.regexで使用できる正規表現修飾子は下表の通りです。 参照: Pattern (Java Platform SE 8 )

Javaの正規表現修飾子の意味
修飾子 対応するオプション 意味
i CASE_INSENSITIVE 大小文字の違いを無視する
d UNIX_LINES Unixラインモードにする
s DOTALL シングルラインモードにする(.が改行にマッチするようになる)
m MULTILINE マルチラインモードにする (^$がそれぞれ改行の直前や直後にマッチするようになる)
u UNICODE_CASE Unicodeに準拠した大小文字を区別しないマッチングを指定する
x COMMENTS 拡張表記を許可する(パターン内でコメントやマッチに影響しない空白が置けるようになる)
(?:regexp)

部分正規表現のグルーピングを行いますが、 \( \)( )とは異なり後方参照を行うことはできません。 たとえば、foo(?:bar)bazfoobarbazという文字列にマッチしますが、 foo(bar)bazの場合とは異なり、 \1(またはそれに相当するもの)にはなにもセットされません。

(?=regexp)

括弧内にある正規表現が続くことを要求する表明です。 マッチの結果の文字列には影響しません。 例えば、else(?= if)という正規表現はelse ifにマッチしますが、 Perlの$&のような正規表現全体にマッチした文字列はelseとなります (当然ながら、 ifが後続していないelseにはマッチしません)。

よくある勘違い
(?=foo)bar のように記述しても、「fooのあとにbarが続いている文字列」には なりませんfooを先読みしてマッチのポイントは動かしませんので(それが先読みだから)、 その場所にbarがあるかどうかで判断します。 マッチのポイントより前にある文字列が存在するかどうかという判定ではありません (それをするのは戻り読み)。

「表明」(もしくは「言明」)という言葉が使われていることにわかりづらさを感じる人もいるようですが、 そのような人はこれを ^$と同じように「位置にマッチする」と考えてみてはどうでしょうか。 ~が見える位置、~が見えない位置といった具合です(かえってわかりづらくしたりして)。

(?!regexp)

(?=regexp)と似ていますが、 こちらは括弧内にある正規表現が続かないことを要求する表明です。

肯定先読みと同様に、 「ある文字列が先行していない文字列にマッチ」させるためにこの表明を使うことはできません。

(?<=pattern)

括弧内にある正規表現が先行していることを要求する表明です。 マッチの結果の文字列には影響しません。例えば、(?<=\t)\wという 正規表現はタブに続く単語にマッチしますが、 マッチした文字列全体を表す $&(Perlの場合)にはタブは含まれません。 戻り読み(もしくは後読み (lookbehind))は固定長の文字列に対してのみ働きます (処理系による。可変長の文字列を許可する処理系もあります→詳細)。

(?<!pattern)

括弧内にある正規表現が先行していないことを要求する表明です。 マッチの結果の文字列には影響しません。例えば、 (?<!foo)barという正規表現はfooが先行しないbarにマッチしますが、 マッチした文字列全体を表す $&(Perlの場合)にはfooは含まれません。 戻り読み(もしくは後読み (lookbehind))は固定長の文字列に対してのみ働きます (処理系による。可変長の文字列を許可する処理系もあります)。

(?>pattern)

一旦マッチした部分正規表現を放棄してバックトラックすることのないパターンです。 したがって、(?>a+)abは何にもマッチしません。 カッコ内のパターンがすべてのaを消費し、 それを手放さないためです。

(?(condition)yes-pattern|no-pattern)
(?(condition)yes-pattern)

条件式です。 ここで(condition)は括弧の中に置かれた整数(対応するかっこのペアがマッチしているときに正当) もしくは長さのない lookahead/lookbehind/evaluate の表明であることが期待されます。

Pythonでは条件式に表明を使えません。

.NETでは名前による後方参照の指定ができます。

(?{ code })

Perlにおいて埋め込まれたPerlコードを実行します

(??{ code })

Perlにおいて埋め込まれたPerlコードを実行してその結果を正規表現を表すものとして使用します。

*+

*に似ていますが、決してバックトラックしません。

++

+に似ていますが、決してバックトラックしません。

?+

?に似ていますが、決してバックトラックしません。

{n,m}+
{n,}+
{n}+

{n,m}等に似ていますが、決してバックトラックしません。

(?P<name>...)
(?<name>...) (?'name'...)

マッチした文字列を name という名前で参照できるようにします。

(?<name>...) や (?'name'...)は .NETで使用される表現です

(?P=name), \g<name>
\k<name> \k'name'

対応する(?P<name>...)でキャプチャした文字列を参照します。 \g<name>は置換テキスト中で使う表現です。

\k<name>\k'name'は .NETで使用される表現です

(?P>name)

対応する(?P<name>...)でキャプチャした文字列を参照します。 PCREの再帰的表現で使用します。以下に使用例を挙げます。 バランスの取れた括弧の対にマッチします。

 
      
        (?P<pn>\(((?>[^()]+)|(?P>pn))*\))
      
    
(?<name1-name2>) または (?'name1-name2' subexpression)

.NETで使用できます。

以下 正規表現でのコンストラクトのグループ化 | Microsoft Docs からの引用です。

グループ定義の均等化では、 name2 の定義を削除し、 name2 と name1 の間隔を name1 に格納します。 name2 グループが定義されていない場合、一致はバックトラックされます。 name2 の最後の定義を削除すると、 name2 の以前の定義がわかるため、この構成体によって、 かっこや左右の角かっこなど入れ子になった構成体を追跡するカウンターとして name2 グループのキャプチャのスタックを使用できます。

グループ定義の均等化では、 name2 をスタックとして使用します。 入れ子になった各構成体の開始文字が、 グループとその Group.Captures コレクションに配置されます。 終了文字が一致すると、 対応する開始文字がグループから削除され、 Captures コレクションが 1 つ減らされます。 入れ子になったすべての構成体の開始文字と終了文字が一致したら、name2 は空になります。

(?R)

PCREで再帰的にパターンにマッチする表現です。

(?num)

PCREで再帰的にパターンにマッチする表現です。 (?R)に似ていますが、 こちらはパターン全体ではなくnumに対応するキャプチャされた部分正規表現が再帰の対象です。 この例もバランスの取れた括弧のペアにマッチします。

      (\()?[^()]+(?(1)\))
    

次のような使い方もできます。

      (sens|respons)e and (?1)ibility
    

これは\1を使ったものとは異なり、 sense and responsibilityにもマッチします。

(?(R)...)

PCREで再帰的パターンの開始を示します。

      
        <(?:(?(R)\d++|[^<>]*+)|(?R))*>
      
    
\p{name}, \P{name}

ブレースに囲まれた名前で指定されたキャラクタ集合に属するキャラクタを指定します。 指定できるキャラクタ集合は一般に、Unicodeのプロパティ、スクリプト、ブロック、カテゴリです。 処理系によっては使える集合が制限されていたりします。

各エスケープシーケンスの説明

正規表現リテラル中で使えるエスケープシーケンスです。 文字列中で使えるものと共通しているもの、していないものがあります。

\a

警告(ベル)です。

\b

バックスペースを表しますが、使えるのが文字クラス内に制限される処理系があります。

\e

エスケープ文字。Perl、PCREで使えます。

\n

改行。

\r

キャリッジリターン。

\f

改ページ。

\t

水平タブです。

\octal

2~3桁の8進表現文字です。数値が3桁に満たない場合は0を数値に前置します(後方参照と区別するため)。

\xhex
\xxxx

16進表現文字です。何桁の表記か可能かどうかが処理系によって異なる場合があります(一桁でも可とか)。

\x{hex}

Perl等で使えるもので任意長の16進表現文字です。

\cchar

Perl等で使えるもので、制御キャラクタをあらわします。 例えば \ci は水平タブになります。

\c[\c\はそのままでは記述できない場合があります。 そのようなときは文字クラスの中に入れたり、\c\\のようにすることで回避できるかもしれません。

\C-char

Rubyで使えるもので、制御キャラクタをあらわします。例えば\C-jは改行コードになります。

\M-char

Rubyで使えるもので、charと\x80をbitwise or したコードになります。 例えば \M-@ は\xc0と等価です。Emacsでいうところのメタな文字です(正規表現のメタキャラクタと混同しないように)。

\uhhhh
\Uhhhhhhhh

Pyhton、Tcl等で使えるもので、それぞれ四桁、八桁の16進数表現文字です。 Perlでは\u\U のどちらにも別の意味があります。

\N{name}

Perl、Pythonで使えるもので名前付けられたキャラクタを表します。詳しくは charnamesを参照してください。

\R
Ruby において、改行文字を表すもの
\X
Ruby において、Unicode の結合文字シーケンスを表すもの

ある文字列を含まない正規表現

提案から実装まで 9 年も掛かってしまいましたが、 鬼車の中の人と Ruby の間の確執がなければとっくの昔に実装されていたのだろうかと思ったり思わなかったり。 ( 鬼雲に非包含オペレータを実装した話 - Qiita)

おにいさん、それは言わないヤクソク……

某巨大掲示板のとあるスレッドの情報によれば、 非包含オペレーターが期待通りに動かないパターンがあるようです。

鬼車 (kkos/oniguruma: regular expression library) でも、2017年8月のVersion 6.5.0から同様の正規表現演算子がサポートされています。

  2017/08/03: Version 6.5.0
  
  2017/07/30: [new] support Absent clear (Absent functions)
  2017/07/25: abolish configure option: --enable-combination-explosion-check
  2017/07/23: [new] support Absent functions (?~...)
  2017/07/14: fix #65: SIZEOF_SIZE_T doesn't exist on certain architecutres
  2017/07/11: [new] support \O (true anychar)
  2017/07/10: [new] support \K (keep)
  2017/07/10: add new node type: NODE_GIMMICK
  2017/07/07: [new] support \N (no newline)
  2017/07/05: [new] support \R (general newline)
  2017/07/05: [new] support if-then-else syntax
  2017/07/04: [new] support backref validity checker  

以上 oniguruma/HISTORY at master · kkos/oniguruma より引用。

    <不在機能群>
  (?~不在)          不在繰り返し  (*原案 田中哲)
                    これは .*(より正確には\O*)のように動作するが、<不在>に
                    適合する文字列を含まない範囲に制限される。
                    これは(?~|(?:不在)|\O*)の省略表記である。

  (?~|不在|式)      不在式  (* 原作)
                    これは<式>のように動作するが、<不在>に適合する文字列を
                    含まない範囲に制限される。

                    例 (?~|345|\d*)  "12345678"  ==> "12", "1", ""

  (?~|不在)         不在停止 (* 原作)
                    この演算子を通過した後は、対象文字列の適合範囲が
                    <不在>に適合する文字列を含まない範囲に制限される。

  (?~|)             範囲消去
                    不在停止の効果を消して、初期の状態にする。

     * 不在機能の入れ子には対応しておらず、その場合の挙動は不定とする。
  

以上 oniguruma/RE.ja at master · kkos/oniguruma より引用。

非包含パターンに関するリンク


ReDOS


その他

Are Regular Expressions a Lingua Franca? An Empirical Study on the Re-use and Portability of Regular Expressions : programming 経由で Are Regular Expressions aLingua Franca?An Empirical Study on the Re-use and Portability of Regular Expressions からABSTRACT をちょっと抜き出し。

    ABSTRACT
  

This paper explores the extent to which regular expressions (regexes)are portable across programming languages. Many languages offer similar regex syntaxes, and it would be natural to assume that regexes can be ported across language boundaries. But can regexesbe copy/pasted across language boundaries while retaining theirsemantic and performance characteristics?

In our survey of 159 professional software developers, most in-dicated that they re-use regexes across language boundaries and about half reported that they believe regexes are a universal lan-guage.

We experimentally evaluate the riskiness of this practiceusing a novel regex corpus — 537,806 regexes from 193,524 projects written in JavaScript, Java, PHP, Python, Ruby, Go, Perl, and Rust.

Using our polyglot regex corpus, we explore the hitherto-unstudiedregex portability problems: logic errors due to semantic differ-ences and security vulnerabilities due to performance differences. We report that developers’ belief in a regexlingua francais un-derstandable but incorrect.

Though most regexes compile acrosslanguage boundaries, 15% exhibit semantic differences across lan-guages, and 10% exhibit performance differences across languages.

We explained these differences using regex documentation, andfurther illuminate our findings by investigating regex engine im-plementations. Along the way we found bugs in JavaScript-V8,Python, Ruby, and Rust, as well as thousands of modules affected by potential semantic and performance regex bugs. Regexes are not alingua franca— almost, but not quite.


ホームページへ

リンクについてはご自由に。 質問、指摘等は kbk AT kt DOT rim DOT or DOT jp まで。