Perl/正規表現

出典: フリー教科書『ウィキブックス(Wikibooks)』
移動先: 案内検索

Perl > 正規表現


Perlは強力な正規表現をサポートしています。その強力さゆえに、初めは少し難しく感じるかも知れませんが、少し慣れれば自由自在に操ることができ、そして、なくてはならない道具となることでしょう。

基礎[編集]

マッチング[編集]

$foo =~ /bar/;

このコードは $foo が 文字列 bar を含むかどうか真偽値を返します。 正規表現を用いるときに使用する演算子は =~ です。

真偽を返すので、主に条件分岐を行う際に用いられます。

if("Wikibooks" =~ /book/){
  print "Match!";
}else{
  print "Not match.";
}

含むかどうかの結果を反転する演算子 !~ も存在します。

if("Wikibooks" !~ /books/){
  print "Not match.";
}else{
  print "Match!";
}

/.../ 内ではダブルクォーテーション ("...") と同じく、変数やエスケープシーケンスが評価されます。

$bar = "books";
"Wikibooks" =~ /$bar/ # マッチする。

m を前置すると正規表現を囲う記号にスラッシュ以外を用いることができます。 [ ], ( ), < >, { } などの括弧は開き括弧と閉じ括弧が対応するように用います。

$foo =~ m/bar/;
$foo =~ m#bar#;
$foo =~ m@bar@;
$foo =~ m!bar!;
$foo =~ m{bar};
$foo =~ m(bar);

囲み記号にシングルクォーテーションを用いると、変数やエスケープシーケンスが評価されるのを防ぐことができます。

$foo = "books";
"Wikibooks" =~ m/$foo/; # マッチする
"Wikibooks" =~ m'$foo'; # マッチしない


メタキャラクタ[編集]

正規表現において特殊な意味を持つ文字をメタキャラクタと呼びます。

+ * ? . ( ) [ ] { } | \ $ ^

これらの文字をあらわすには \+, \* のようにバックスラッシュでエスケープします。

$foo =~ /\+/;
$foo =~ /\*/;

アンカー[編集]

アンカーとは長さを持たない正規表現です。

代表的なものに、文字列先頭にマッチする ^、文字列末尾にマッチする $ があります。

"Wikibooks" =~ /^Wiki/; # マッチする
"Wikibooks" =~ /book$/; # マッチしない

他に、単語の境界(正確には、単語の先頭あるいは末尾)にマッチする \b、それ以外の部分にマッチする\B があります。

"Wikibooks"  =~ /Wiki\b/; # マッチしない
"Wiki books" =~ /Wiki\b/; # マッチする

キャラクタクラス[編集]

ブラケットで囲んだ部分はキャラクタクラスになります。 キャラクタクラスはその中のいずれかひとつにマッチする正規表現です。

"Wikibooks" =~ /[ab]/; # a は含まれないが、b は含まれるのでマッチする

ハイフン (-) を用いると文字の範囲を指定することができます。

$foo =~ /[abc]/;
$foo =~ /[a-c]/;   # 上の文と等価
$foo =~ /[01234]/;
$foo =~ /[0-4]/;   # 上の文と等価

ハイフンの前の文字は、後ろの文字よりも文字コードにおいて前でなければなりません。

$foo =~ /[b-a]/; # エラー
$foo =~ /[5-3]/; # エラー
$foo =~ /[a-3]/; # エラー

ハイフン自体をキャラクタクラスに含めるには、キャラクタクラスの一番前か一番後ろに記述するか、バックスラッシュでエスケープします。

$foo =~ /[-ab]/;  # ハイフンまたは a か b にマッチする
$foo =~ /[ab-]/;  # 上の文と等価
$foo =~ /[a\-b]/; # 上の文と等価

開きブラケット ([) に ^ を後置すると、否定キャラクタクラスを表現することができます。

$foo =~ /[^0-9]/; # 数字以外にマッチする

グループ化[編集]

丸括弧で括った部分はグループ化されます。

グループ化した部分は後から参照することができます。これを後方参照といいます。 同じ正規表現内で後方参照を行うには、\1, \2... を用います。

$foo =~ /(abc)\1/; # abc が2回連続する文字列にマッチする

また、正規表現外で後方参照を行うには、スカラー変数 $1, $2... を用います。

"Wikibooks" =~ /(wiki)/i;
print $1; # 'Wiki' と出力される。

選択[編集]

縦線を用いると正規表現を選択することができます。

$foo =~ /abc|def/; # abc あるいは def にマッチする
$foo =~ /^abc|def$/;

これは、^$| よりも優先順位が高いため、abc で始まる文字列か def で終わる文字列にマッチします。

"abc" か "def" にマッチさせるには以下のようにします。

$foo =~ /^(abc|def)$/;
$foo =~ /^abc$|^def$/;

置き換え[編集]

s///演算子を用いると、文字列の置換を行うことができます。

$str = "Wikibooks";
$str =~ s/books/pedia/; # $str は "Wikipedia" になる

m//と同じく、スラッシュ以外の記号を用いることもできます。

$foo =~ s/foo/bar/;
$foo =~ s#foo#bar#;
$foo =~ s@foo@bar@;
$foo =~ s!foo!bar!;
$foo =~ s{foo}{bar};
$foo =~ s(foo)(bar);

修飾子[編集]

正規表現のメタキャラクタ、あるいはパターンマッチそのものの振る舞いを変えるために、修飾子を指定することができます。たとえば、正規表現がアルファベットの大文字小文字を区別せずにマッチするようにするためには、

m/^perl$/i; # perlにもPerlにもPERLにもPeRlにもマッチする。もちろんpErLにもマッチする。

のように、最後のスラッシュ(あるいは何らかの記号)の後に、i修飾子を付加します。

Perlの正規表現の修飾子
i 大文字小文字の同一視 (case-insensitive)
s 「.」が改行にもマッチするようにする (single line)
m 複数行として扱う (multi-line)
x 拡張正規表現を使う (extended)
e Perlのコードとして評価する (evaluation)
ee Perlのコードとして2回評価する (evaluation and evaluation)
g 連続して何回もマッチ (global)
o 一度だけコンパイルする (only once)

拡張正規表現[編集]

x修飾子を付けると正規表現内の空白や改行が無視され、「#」以降はコメントとして扱われます。

# 1と出力
print 1 if "Apple" =~ /
A
p
p
l
e
/x;

アトムとアサーション[編集]

「ABC」や「[0-9]」、「.*?」のように、何かにマッチする正規表現の構文をアトムといいます。最後の「.*?」は、アトム「.」に量指定子「*」、「?」が付いたもので、特に量指定子付きアトムといいます。

「^」や「$」、「|」のように、何かにマッチするわけではない正規表現の構文をアサーションといいます。

正規表現の構文は基本的にアトムとアサーションのどちらかに分けられます。ただし、\Qや\E、\uや\Uのような特殊なシーケンスはアトムでもアサーションでもありません。これらは構文のふるまいを変えるものです。

拡張構文[編集]

コメント[編集]

/(?#ここはコメント)/

クラスタ化専用カッコ[編集]

(?:...)はクラスタ化(正規表現をまとめること)のみに使われるカッコです。キャプチャを行わないため、マッチした部分を正規表現の中で\1、\2のように参照したり、後から$1、$2のような変数で参照したりすることができません。キャプチャを行う必要がない場合は、このカッコを使うことで効率化を図ることができます。

"Apple" =~ /^(?:Apple|Banana|Cherry)$/; # AppleかBananaかCherryにマッチ

これにはimsx修飾子を付けることもできます。i修飾子を付けるには、i-msx(iを指定しmsxを指定しない)とします。

"aPpLe" =~ /^(?i-msx:Apple|Banana|Cherry)$/;

単に修飾子を有効または無効にするためだけにこのカッコを使うこともできます。

/A(?i-msx)B/; # Aは大文字小文字を区別するが、Bは区別しない

ルックアラウンドアサーション[編集]

ルックアラウンドアサーションとは、直後または直前にパターンが出現すること、あるいは出現しないことを確認し、確認するだけで何にもマッチしないアサーションです。

  • 肯定先読み

直後にPATTERNが出現することを確認します。

/(?=PATTERN)/
  • 否定先読み

直後にPATTERNが出現しないことを確認します。

/(?!PATTERN)/

次の例では、「&amp;」以外の「&」をすべて「&amp;」に置換します。

$str =~ s/&(?!amp;)/&amp;/g;
  • 肯定後読み

直前にPATTERNが出現することを確認します。

/(?<=PATTERN)/
  • 否定後読み

直前にPATTERNが出現しないことを確認します。

/(?<!PATTERN)/

非バックトラックサブパターン[編集]

バックトラックしないPATTRENにのみマッチします。

(?>PATTERN)

コードサブパターン[編集]

(?{ CODE })という形で、正規表現の中にPerlのコードを埋め込むことができます。

/(?{ print "Hello, world!\n" })/; # Hello, world!と表示

(??{ CODE })という形では、CODEを評価した結果得られた正規表現にマッチします。

"ABC" =~ /^(??{ "A"."B"."C" })$/; # ABCにマッチする

条件付き展開[編集]

Perlの条件演算子?:のように、条件が真か偽かでマッチさせるパターンを変えることができます。

/(?(COND)TRUE|FALSE)/

または

/(?(COND)TRUE)/

CONDが真の場合はTRUE、偽の場合はFALSEのパターンにマッチします。

このページ「Perl/正規表現」は、書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にノートへどうぞ。

変換[編集]