正規表現

last-modified: 3rd/June/'01;
since: 1st/June/2001;

Perl に仕事をさせるには、条件分岐繰り返し、配列変数、ファイル処理などを学ぶ必要があります。ここでは、 Perl 自身からは少し離れて、「正規表現 (regular expression) 」に付いて紹介します。

正規表現は、 grep, egrep, Perl, Tcl, テキストエディタなどで、文字列の検索と置換の為に使われます。たとえば、あるディレクトリ内の複数のファイルから文字列を検索する場合に、検索対象の文字列の「パターン」を正規表現で記述します。

例えば、文字列「border」を検索したければ、 border と書きます。しかし、例えば「1:15」、「12:20」などの時刻表示の文字列を全て検索したい場合はどうしましょうか?この場合は、「\d+:\d+」と書けば、「数字一回上の繰り返し:数字一回上の繰り返し」を意味します。このような表現方法が正規表現には沢山用意されています。

これを利用するには、幾つかのキマリゴトを覚えておく必要があります。最初に、最低限度のキマリゴトを列挙しておきます。必要があれば参照してください。

メタ文字
.任意の一文字
[string]string に含まれる文字の任意の一文字
[^string]string に含まれない文字の一文字( string の補集合)
^r正規表現 r で始まる行
r$正規表現 r で終わる行
r*正規表現 r のゼロ回以上の繰り返し
c文字 cc はメタ文字以外の任意の一文字)
\m文字 mm はメタ文字)

行頭を示す ^r と、補集合を示す [^string] の違いに注意してください。

メタ文字とは、それ自信が意味を持つ文字のことです。 \ は、メタ文字の意味を奪うエスケープ文字です。

エスケープ文字 \ が必要になるのは、 ^ [ ] ( ) $ . * + - ? \ / などです。特に、 / は Perl スクリプトで正規表現を括るために使われている文字です。 URL などでは次のように書かなければなりません。

$a =~ /http:\/\/www.sugai.f2s.com\/perl\/index.html/

これは面倒なので、正規表現の区切り文字を変更できます。例えば、 #{ } を区切り文字にする場合は、次のようにします。

$a =~ m#http://www.sugai.f2s.com/perl/index.html#
$a =~ m{http://www.sugai.f2s.com/perl/index.html}
メタ文字の使用例
[abcd][yz]一文字目が a, b, c, d の何れかで、二文字目が y, z の何れかである文字列にマッチする。例えば、 ay, az, by, bz など
[\]^[]エスケープ \ によって ] が文字として扱われ、出現位置から ^, [ も通常の文字として扱われます。従って、 ], ^, [ の何れか一文字にマッチします。
[a-d]アルファベットの a から d までの任意の一文字にマッチする。
[0-9+\-]0 から 9 までの任意の一文字か、 +, - にマッチする。
a*a がゼロ回以上繰り返す文字列にマッチする。
\** にマッチする。

以上は、 Mule, vi, grep, Perl, Tcl などで共通する正規表現のメタ文字です。 Perl には他にも沢山のメタ文字が存在します。以下に挙げるものは、 Perl 以外では存在しないか、微妙に表記方法が異なる場合があるモノです。これらを使うと、非常に柔軟性の高い文字列検索作業が実現できます。

Perl の正規表現のメタ文字
r+正規表現 r が一回以上繰り返す文字列(rr* と同じ)
r?正規表現 r がゼロ回、または一回出現する文字列
( )カッコ内をグループ化。
r1|r2正規表現 r1r2 の出現。
\n後方参照。 n 番目のグループを参照。

以下に使用例を示します。

メタ文字の使用例
(ab|cd)+ab, cd, abcd, cdab, abcdabab,...
((ab|cd)+)_\1ab_ab, cd_cd, abcd_abcd, cdab_cdab, abcdabab_abcdabab,...

((ab|cd)+)\1 は、第一グループ (ab|cd)+ にマッチした文字列が \1 によって参照されているので、「第一グループにマッチする文字列が二回繰り返された文字列」にマッチすると云う訳です。

別の例として、 「<」 と 「>」 に括られた文字列にマッチして欲しい場合を考えましょう。一見、「 <.*> 」とすれば良いように思えます。しかし、これではマズイのです。次のようなサンプルがあったとします。

これは<em>サンプル</em>です。

この場合、「 <em> 」と「 </em> 」の部分にマッチして欲しい筈ですが、実際には「 <em>サンプル</em> 」にマッチしてしまいます。これは Perl では、マッチするパターンのものの、最長部分にマッチする原則があるからです。これを最長一致と呼びます。便利な機能ですが、今の場合は不適切です。これを回避する為に、「 <.*?> 」とすることで、マッチするパターンの中で最も短い部分にマッチしてくれます。これを、最短一致と呼びます。

一般に、繰り返しのメタ文字に ? を加える事で、最短一致のメタ文字になります。憶えておいてください。

最短一致
*?ゼロ回以上の最短繰り返し。
+?1 回以上の最短繰り返し。
??ゼロ回又は 1 回の最短繰り返し。できればゼロ回、 1 回だけなら出現してもマッチする。
{n,m}?n 回以上 m 回以下の範囲内で最短繰り返し。

例えば、 abbbc に対して、 ab* とすれば、 abbb にマッチします。 ab*? とすれば、 ab にマッチします。 ab{4,6} ではマッチしません。 ab{2,4} ならば abbb にマッチします。 ab{2,4}? ならば abb にマッチします。

最後に、その他の正規表現を列挙しておきます。

Perl の正規表現 -2-
繰り返し
r{n,m}正規表現 rn 回以上 m 回以下の繰り返し。
r{n,}正規表現 rn 回以上の繰り返し。
r{n}正規表現 rn 回の繰り返し。
エスケープシーケンス
\n改行
\tタブ文字
\rリターン
\f改頁文字
\b[ ] 内でバックスペース文字。
\b[ ] 外で単語境界。
\B単語境界以外。
\aアラーム
\0ヌル文字
\xhh文字の16進数表現。 h = hexadecimal
\oooo文字の8進数表現。 o = octal
\cctrlコントロール文字。

以上で、 Perl における正規表現のメタ文字を網羅しました(多分)。正規表現は基本的にはメタ文字を含んだ文字集合で表します。次に、良く使う文字集合の省略形を紹介します。

Perl の文字集合の省略形
\w[0-9A-Za-z_] と等価。英数字全て。
\W[^0-9A-Za-z_] と等価。英数字以外。
\d[0-9] と等価。数字全て。
\D[^0-9] と等価。数字以外。
\s[ \n\r\f\t] と等価。半角空白、改行、リターン、改頁文字、タブ文字。つまり、空白類文字。
\S[^ \n\r\f\t] と等価。空白類文字以外。
Copyright: SUGAI, Manabu. Since: 2001