正規表現(regular expression)の基礎

1 正規表現とは

 正規表現は、ある文字の並び(文字列)を表現する一つの方式です。「文字の並び」のことを「パターン」と言ったりもします。でも、基本的には単なる文字列です。
 例えば、 abc という3文字を示すための正規表現は、それと全く同じ abc という3文字です。 list という4文字を示す正規表現は、それと全く同じ list という4文字です。なんだ、つまらない。
 これだけで終わってしまったんじゃ、ほんとにつまらないですが、残念ながら難しいことで悪名高き正規表現は、これで終わりになりません。次のような例を考えてみて下さい。

 文書中に 「第1章」とか「第2章」とか「第3章」といった記述があるとします。今、検索したいのは1章でも2章でも何でもいいんですが、とにかく「第X章」だとしましょう。Xは、何でもいいという訳です。このような場合、正規表現が使えると便利です。正規表現には、「何でもいい1文字」を表現する手段があるからです。このケースでは、例えば
  第.章
という3文字を検索文字列に指定すると、 第1章 第2章 第3章 といった文字列が検索されます。「第.章」という3文字の真ん中にある半角ピリオドは、正規表現において特別の意味を持たされた文字で、メタキャラクタと呼ばれます。その特別の意味というのは、「何か1文字」つまり「何でもいいけど、とにかく1文字」を表現するということです。この半角の . (ピリオド)は、「何でもいい1文字」とマッチするという言い方もします。
 だとすれば、文字としての半角ピリオドを表現する時はどうするか?その時は、半角の \ (円マーク)を前に置きます。例えば、円周率 3.14 という4文字を示す正規表現は、 3\.14 という5文字になります。
 半角の \ 1文字を表現する時は、 \\ という2文字になります。
 (\は、パソコンの機種によっては円マークでなくバックスラッシュの形で表示されるケースもあるかと思います。)

 この半角ピリオドのように、正規表現では、特別の意味を持たされている文字(メタキャラクタ)がいくつかあります。以下にそれらを上げて説明します。

2 正規表現の特殊文字(メタキャラクタ)

 以下、メタキャラクタを一つづつ上げます。ここに上げたメタキャラクタ以外の文字については、正規表現において特別の意味はありません。単に普通の文字として扱って大丈夫です。

2.1 ^ (羃乗)

 半角の ^ は、行頭を示します。例えば
  ^abc
という4文字は、行頭が abc で始まるパターンを表現します。行の途中に abc という3文字があっても、それとはマッチしません。

2.2 $ (ドルマーク)

 この半角の $ は、 ^ に似ていますが、行の終わりにマッチします。たとえば、
  です。$
という4文字は、行末にある「です。」という3文字とマッチします。行の途中にある「です。」という3文字とはマッチしません。

2.3 . (ピリオド)

 半角の . (ピリオド)は、任意の1文字にマッチします。ただし、改行コードとはマッチしません。改行コード以外の1文字を示します。

2.4 [……] (大括弧と大括弧閉じによる囲み)

 [と]の二つで囲まれたものを「クラス」とか「文字セット」といいます。囲みの中に書かれた任意の1文字にマッチします。たとえば、
  [abc]
という5文字は、 a, b, c の3文字のいずれか1文字を表現します。3文字のうちどれでもいいのですが、とにかく1文字とマッチします。また
  [0123456789]
という12文字は、 0~9 の10個の数字のうちの1文字とマッチします。もう少し例を上げると
  [abc][0123456789]
という17文字は、 a0 a1 a2 a3 とか b0 b1 b2 b3 あるいは c0 c1 c2 などの2文字とマッチします。

 ところで、該当の文字を一つづつ全て書かなければいけないとすると、ちと面倒です。これを便利に記述する方法もあります。例えば
  [0123456789]
という12文字は
  [0-9]
という5文字で表現することができます。この場合の半角の - (マイナス)は、範囲を表わす特別の文字です。
  [A-Z]
という5文字は、半角アルファベットノ大文字1文字トマッチします。また、次のような記述も可能です。
  [A-Za-z_]
これは、半角のアルファベット(大文字でも小文字でもかまわない。)と半角の _ のうち、いずれか1文字とマッチします。
  [亜-腕]
という5文字は、第1水準漢字1文字を表現します。このように文字を(アスキーコード・JISコードの順序に配慮しながら)範囲指定で表現することができます。

2.5 [^……] (大括弧・羃乗・大括弧閉じ)

 これは、クラスの否定です。指定された文字集合以外の1文字を表現します。例えば
  [^0-9]
という6文字は、「半角数字以外の任意の1文字」を表現します。アルファベットとか漢字等々半角の数字以外なら何でもいい訳ですね。もちろん
  [^abcd]
とか
  [^A-Za-z_]
などといった記述も可能です。

2.6 | (縦線)

 これは、「または」という接続詞に該当するものです。例えば
  abc|main
という8文字は、 abc という3文字か、または、 main という4文字にマッチします。
  ^abc|^main
という10文字は、「行頭が abc である行」または「行頭が main である行」とマッチします。いずれか一方とマッチすればいい訳ですね。
  ^abc|main$|list.
などのように三つ以上のパターンをつなげても大丈夫です。

2.7 * (アスタリスク、または米印ともいう)

 半角の * は、直前の1文字の0回以上の繰り返しを表現します。例えば
  a*
という2文字は、 a aa aaa aaaa などとマッチします。そのほか、「aという文字がない状態」ともマッチします。これは、ちょっと分かりにくいですね。例えば、
  abc*
という4文字は、 ab abc abcc abccc abcccc などとマッチすると書けば、少しは分かりやすいでしょうか。
 ここで少し面倒な話を一つ。 a* のような場合は、「文字が何もない状態」をも示します。それでは、この a* の2文字を検索文字列に指定して実際に検索作業をするとどうなるでしょう?いわば「何とでもマッチする」ということになってしまいます。非常に不安定な検索文字列といえます。こうした検索文字列は指定しない方がいいです。

2.8 + (プラス)

 半角の + は、直前の1文字の1回以上の繰り返しを表現します。半角の * が0回以上の繰り返しだったのに対し、こちらは1回以上の繰り返しです。
  abc+
という4文字は、 ab にはマッチしません。 abc abcc abccc などにマッチします。
 参考までに書いておくと…… .+ という2文字は、あらゆる文字列とマッチします。この正規表現は、任意の1文字の1回以上の繰り返しという意味になりますから、文字が何もない状態(つまり空白行)以外なら何とでもマッチするということになります。最初に示した例の「第.章」というのは、第1章とか第2章等とはマッチしますが、数字部分が2桁以上になる「第11章」のような場合にはマッチしません。それに対し「第.+章」とすれば第123章みたいなものにもマッチするということになります。.+ の2文字は、あまりに多くのものとマッチし過ぎるという嫌いはありますが、利用の仕方によってなかなか便利です。
 (もし「第」と「章」の間にくるものを厳密に数字だけに限定するのなら「第[0-90-9]+章」とすべきです。こうすれば、半角・全角の数字が間に挟まれる場合以外はマッチしないことになります。)

2.9 ? (疑問符)

 半角の ? は、直前の文字の0回または1回だけの登場を表現します。例えば
  abc?
という4文字は、 ab abc のいずれかにしかマッチしません。

2.10 (……) (括弧と括弧閉じによる囲み)

 半角の ( と、同じく半角の ) で囲んだ部分は、一つのまとまり、グループとみなします。もちろん、正規表現をこれで囲んでもかまいません。例えば
  (abc)+
という6文字は、 abc abcabc abcabcabc などとマッチします。

2.11 \ (円マーク)

 半角の \ は、メタキャラクタの特別の意味を打ち消すためのものです。正規表現の中では、例えば ^ という文字を表現したい時には \^ と2文字で書き表わさなければなりません。半角の . は、 \. です。
 半角の \ を表現したい時は、 \\ と2文字を書いて下さい。

 以上が、正規表現のメタキャラクタと呼ばれるものの紹介です。これを縦横無尽に使えるようになると、文字列の検索がきめ細かく行えるようになります。
 とは言っても、普通それほど複雑な正規表現検索を使うことは あまりないと思います。任意の1文字を示すピリオド、1回以上の繰り返しを示すプラス… といったところを使えれば、それだけで単なる文字列検索よりもかなり便利になるんじゃないかと思います。

3 補足

 正規表現は、UNIX系コマンドで多く採用されています。例えば、grep, sed, awk, perl, emacs …… といったコマンドで採用されています。(Windows上で動作するソフトでも WZエディタなどでは正規表現が使えます。)そして、実はコマンドによって正規表現の記述方法が少しだけ異なります。ですが、上に掲げた正規表現のルールは、ベーシックといっていいと思います。
 インターネットサーバによく組み込まれている perl では、次のような記述も行えます。なかなか便利なので上げておきます。

 それから、「最長一致の原則」というのも一応念頭に置いておいて下さい。ある正規表現が同じ文字列の異なる長さの部分にマッチする場合、最も長い部分というのか、最も包括的な部分にマッチするというのがこの原則です。
 例えば、「第1章と第2章」という7文字からなる文字列があったとすると、「第.+章」という正規表現は、「第1章」とマッチするとも考えられるし、「第2章」とマッチするとも考えられるし、はたまた文字列全体の「第1章と第2章」にもマッチするといえます。でも、こういう場合は「最長一致」ということで文字列全体とマッチするというのが正解です。

 もっと詳しく正規表現について知りたい方は、例えば、次のサイトを参照してみて下さい。
Regular Expression(Riue ちゃんの正規表現講座) - Index
正規表現メモ

 以上、おしまい。


タートルの会ホームページ内の検索 |  トップページ