正規表現

正規表現（せいきひょうげん、）は、文字列の集合を一つの文字列で表現する方法の一つである。とも呼ばれ、形式言語理論の分野では比較的こちらの訳語の方が使われる。まれにあるいはと呼ばれることもある。
もともと正規表現は形式言語理論において正規言語を表すための手段として導入された。形式言語理論では、形式言語が正規言語であることと正規表現によって表せることは同値である。
その後正規表現は単機能の文字列探索ツールやテキストエディタ、ワードプロセッサなどのアプリケーションで、マッチさせるべき対象を表すために使用されるようになり、表せるパターンの種類を増やすために本来の正規表現にはないさまざまな記法が新たに付け加えられた。このような拡張された正規表現には正規言語ではない文字列も表せるものも多く、ゆえに正規表現という名前は実態に即していない面もあるが、伝統的に正規表現と呼ばれ続けている。
この記事では主にこのような正規表現を用いたパターンマッチングについて説明している。以下、誤解のない限り、アプリケーションやプログラミングにおいて正規表現を用いた文字列のパターンマッチングを行う機能のことを、単に正規表現という。
ほとんどのプログラミング言語では、ライブラリによって正規表現を使うことができる他、一部の言語では正規表現のリテラルもある。「正規表現によるマッチ」を意味する（専用の）演算子がある言語なども一部ある。具体例として、grep, AWK, sed, Perl, Tcl, lex などがある。
それぞれの言語やアプリケーションで細部の仕様が異なっている、といったように思われることも多いが（古い実装では実際にそのようなことも多い）、近年は同じライブラリを使っていれば同じということも多い。またPOSIXなど標準もある。
基本的な概念.
理論的に明解であり扱いも容易であるため、形式的な説明を先に述べる。
形式的な説明.
記号（アルファベット）formula_1 上の正規表現は次のようなものから成る。正規表現があらわす記号列（アルファベット列）の集合によって形式言語が定義される。
正規表現の定義に、次の項目を含めることもある:
正規表現 formula_20 の表す集合は正規表現 formula_24 の表す集合に等しいので、formula_20 を正規表現の定義に含めなくても formula_24 で代用できる。
formula_10 の代わりに formula_28 と書くことや、formula_13 の代わりに formula_30 と書くこともある。また、「formula_31」や「formula_32」の優先順位を明確にするために、補助的なカッコも（上述の定義には含めていないが）必要である。
実用的説明.
以下ではもっぱらよく使われているライブラリやツールなどの実用的な観点から説明する。
例えば、「codice_1」「codice_2」「codice_3」という3つの文字列を含む集合は「codice_4」というパターンで表現できる（あるいは、パターンは個々の3つの文字列にマッチすると言われる）。ほとんどの形式では、もし特定の集合にマッチする何らかの正規表現が存在すれば、無限の数のそのような表現がある。ほとんどの形式では正規表現を構築するために次の演算子を提供している。
これらの構文は任意の複雑な表現を形成するために組み合わされて使用される。
歴史.
正規表現の起源は、言語学と、理論計算機科学の一分野であるオートマトン理論や形式言語理論にみることができる。20世紀の言語学では数理的に言語を扱う数理言語学が発展しその過程の一部として、また後者は計算のモデル化（オートマトン）や形式言語の分類方法などを扱う学術分野である。数学者のスティーヴン・クリーネは1950年代に正規集合と呼ばれる独自の数学的表記法を用い、これらの分野のモデルを記述した。
Unix系のツールに広まったのは、ケン・トンプソンがテキストファイル中のパターンにマッチさせる手段として、この表記法をエディタQEDに導入したことなどに始まる。彼はこの機能をのエディタにも追加し、後に一般的な検索ツールであるgrepの正規表現へと受け継がれていった。これ以降、トンプソンの正規表現の適用にならい、多くのUnix系のツールがこの方法を採用した（例えば , , , , , など）。
との正規表現はヘンリー・スペンサー()によって書かれたものから派生している（Perlは後にスペンサーの正規表現を拡張し、多くの機能を追加した）。フィリップ・ヘーゼルはの正規表現とほぼ互換のものを実装する試みとして (PCRE) を開発した。これはPHPやなどといった新しいツールで使用されている。
Rakuでは、正規表現の機能を改善してその適用範囲や能力を高め、を定義できるようにする努力がなされた。この結果として、文法の定義だけでなくプログラマのツールとしても使用できる、と呼ばれる小言語が生み出された。
（本来の）正規表現からの拡張は各種あり便利であるがその多くは、（本来の）正規言語から逸脱するものであり、キャプチャなどが代表例である。なお、正規言語から逸脱しないことによって理論的な扱いが可能になるという利点があるため、例えば「非包含オペレータ」の提案ではそういった観点からの理由も挙げられている。
Rakuに限らずいくつかの実装では、（Perlではsubpatternと呼んでいる）部分パターンの定義とその再帰的な呼出しにより、例えばカッコの対応などといった（本来の）正規表現では不可能なパターンも表現できる。これは、対象部分にマッチした文字列が捕獲され、後から利用できるキャプチャとは異なり、パターンそのものの定義と利用である。PHP, Perl, Python（regexライブラリ）, Ruby などで利用できる。
構文.
標準.
UNIXの標準であるPOSIXでは、単純正規表現、基本正規表現、拡張正規表現の3種類の記法が示されている。このうち、単純正規表現は「歴史的」また「レガシー」と書かれており、後方互換性を提供するものとされ、標準の将来の版では廃止され得ると注意されている。
単純正規表現.
単純正規表現はSREとも呼ばれる。その仕様は「codice_32」のマニュアルページとして示されている。
基本正規表現.
基本正規表現はBREとも呼ばれる。ほとんどの正規表現を利用する UNIXのユーティリティ（grepやsed）のデフォルトはこれである。
この文法では、ほとんどの文字はリテラル（機能を意味せず書かれたそのまま）に扱われる。つまり、ある文字はその文字にのみマッチする。例えば、正規表現「codice_11」は文字「codice_11」にマッチし、正規表現「codice_35」は文字列「codice_35」にマッチするなど。例外はメタ文字と呼ばれる。
古いバージョンのgrepは選言演算子「codice_37」をサポートしていない。
例
符号点の範囲によってたとえば「アルファベット大文字」などを表現しようとすることは、時に問題をひきおこす。たとえばロケールに依存する例として、エストニア語のアルファベット順では、文字「s」の後に「z」があり、その後は「t」「u」「v」「w」「x」「y」と続くので、正規表現「codice_54」ではすべての言語のすべてのアルファベット小文字にマッチするわけではない。そのため、 標準では次の表に示されているクラス、つまり文字の区分を定義している。
例:正規表現「codice_55」は英語の大文字「codice_56」〜「codice_57」と「codice_11」と「codice_59」のうち1文字のみにマッチする。
いくつかのツールで使用できる、 にないクラスとして「codice_60」がある。「codice_60」は通常「codice_62」と[[アンダースコア]]からなる。これらが多くの[[プログラミング言語]]で[[識別子]]として使用できる文字であることを反映している。
拡張正規表現.
拡張正規表現はEREとも呼ばれる。より現代的な拡張正規表現は多くの場合、現在の のユーティリティで[[コマンドライン]]オプションに「codice_63」を含めることで使用できる。
の拡張正規表現は伝統的な の正規表現に似ているが、いくつかの点で異なっている。
例えば、拡張正規表現「codice_64」は文字列「codice_65」や文字列「codice_66」にマッチする。
の正規表現.
 codice_67コマンドにおけるデフォルトの正規表現文法としても用いられる。（findutils-4.2.28）
GNU Emacs Manual - Regexps
Perlの正規表現.
はの拡張正規表現さえも上回る豊富な文法を持っている。その例として、POSIXとは異なり、Perlの正規表現には「非欲張り量指定子」がある。標準の「codice_16」は、例えば、正規表現「codice_69」の「codice_70」はできるだけ長い文字列にマッチしようとする。このふるまいを「貪欲」という。たとえば文字列「codice_71」にマッチさせると、全体にマッチする。これに対し、では使うことができる正規表現「codice_72」の「codice_73」は、マッチするのであれば、できるだけ短い文字列にマッチする。たとえば文字列「codice_71」に対して「codice_75」にだけマッチする。これを「非欲張り量指定子」と言う。
また、Perlには以下の定義済み文字クラスがある。
すぐれた機能をもつPerlの拡張正規表現は、多くの[[プログラミング言語]]やソフトウェアで採りいれられている。例えば、[[Java]]のPattern[[クラス (コンピュータ)|クラス]]、[[Python]]、[[Ruby]]などがそうである。しかし、これらがPerlの正規表現と完全に互換である訳ではない。また、[[Perl Compatible Regular Expressions]] (PCRE) と呼ばれる汎用の正規表現ライブラリはアプリケーションに組み込まれ、Perlの正規表現とほぼ互換の機能を提供する。
正規表現ライブラリ.
言語処理系やアプリケーションが正規表現をサポートしていない場合であっても、正規表現に必要な処理を提供する外部ライブラリを導入することで正規表現を使うことができる。以下にその一例を挙げておく。
外部リンク.
[[Category:プログラミング]]
[[Category:構文解析 (プログラミング)]]
[[Category:コンピュータ言語]]
[[Category:表現]]
[[Category:ケン・トンプソン]]