Go to the first, previous, next, last section, table of contents.


正規表現の書き方

パターンマッチで用いるパターンは、Version 8 regexp ルーティンで提供され ているような正規表現です。(実際、使用しているルーティンは、Henry Spencer が書き直した再配布可能な V8 のルーティンを元にしています。)詳しくは、 「See section Version 8 正規表現,」の節を参照してください。

特に、以下のメタ文字は、標準的な egrep(1) と同様の意味を表わします:

デフォルトでは、文字 "^" は文字列の最初にだけ、文字 "$" は最後 (もしくは、 最後の改行の前) にだけマッチすることが保証されており、Perl は文字列には 1 行だけが含まれていると仮定して、最適化を行ないます。文字列の中に埋め込 まれた改行は、"^" や"$" はマッチしません。しかし、文字列を複数行のバッファ として扱い、"^" はすべての改行のあとにマッチし、"$" はすべての改行の前に マッチするようにしたい場合もあるでしょう。少しばかり負荷がかかりますが、 パターンマッチ演算子に /m 修飾子を付けると、そのようにすることができるよ うになります。(昔のプログラムでは $* を設定することでこれを行なっていま したが、Perl 5 でこれを行なうことは芳しくありません。)

複数行の置換を容易にするため、/s 修飾子を使わない限り、文字 "." は改行文 字にマッチしません。この /s 修飾子は、文字列がたとえ複数行であっても単一 行であるかのように扱うよう Perl に指示するものです。/s 修飾子は、他のモ ジュールで $* を設定するような (よくない) 過去のコードを持ってきたような 場合にも、その $* の設定を無効にします。

次のような標準の数量子が認識されます:

(中括弧が他の文脈であらわれた場合には、通常の文字として扱われます。) "*" 修飾子は {0,}、"+" は {1,}、"?" は {0,1} と等価なものとして扱われます。n や m の大きさに制限はありませんが、大きな数はそれだけメモリを消費します。

デフォルトでは、数量子を付けたサブパターンは、「最長一致」となり、残りの パターンがマッチしなくならない範囲で、できる限り多くのものにマッチするよ うになっています。つまり、標準の数量子は、すべて「最長一致」で、(適切な 開始位置を与えると) パターンが失敗しない範囲で可能な限り長い範囲にマッチ します。もし、最短の範囲でマッチさせたいのであれば、数量子の後に "?" を 付けて指定します。この場合、「最短一致」となるだけで、意味するところは変 わりありません:

パターンはダブルクォート文字列として処理されますから、

\t          タブ
\n          改行
\r          復帰
\f          改ページ
\v          垂直タブ (それが何であっても)
            (訳注: これは使えないように見える)
\a          アラーム (ベル)
\e          エスケープ
\033        8 進数で表した文字
\x1b        16 進数で表した文字
\c[         コントロール文字
\l          次の文字を小文字にする
\u          次の文字を大文字にする
\L          \E まで小文字にする
\U          \E まで大文字にする
\E          変更の終わり
\Q          \E まで正規表現のメタ文字をクォートする

も使用できます。さらに、Perl では以下のものが定義されています:

\w  「単語」の構成文字 (英数字と "_") にマッチ
\W  単語の構成文字以外にマッチ
\s  空白文字にマッチ
\S  空白文字以外にマッチ
\d  数字にマッチ
\D  数字以外にマッチ

\w は 1 字の英数字にマッチするのであって、単語全体にマッチするのではない ことに注意してください。単語全体にマッチさせるためには \w+ とする必要が あります。\w, \W, \s, \S, \d, \Dは文字クラス内 (で範囲を指定する両端の文 字以外の場所) でも使うことができます。

Perl では以下の長さのない、位置指定子を定義しています:

\b  単語の境界にマッチ
\B  単語の境界以外にマッチ
\A  文字列の最初にのみマッチ
\Z  文字列の最後にのみマッチ
\G  前回の m//g が終わったところにのみマッチ

単語の境界 (\b) は \w で定義される文字と \W で定義される文字の間というよ うに定義されます (順番はどちらが先でもよい)。文字列の最初と最後には \W に含まれる仮想的な文字があるものとして扱われます。(文字クラスの中では \b は単語境界ではなく、バックスペースを表わします。)\A と \Z は /m 修飾子が 用いられた場合にも 1 か所でしかマッチしないことを除いて "^" と "$"と同じ 事になります。"^" と "$" は内部的な行の境界にもマッチします。

括弧括り ( ... ) の形式を用いている場合には、\<数字> がその括られている 「数字」番目の部分文字列にマッチします。(パターンの外では、数字の前の "\" の代わりに "$" を使います。) $<数字> (と $`, $&, $') のスコープは、 BLOCK や eval 文字列の終わりや、次の部分式を使ったパターンマッチまでとな ります。サブパターンとして記録せずに、括弧で括ってサブパターンを区切りた い (たとえば、選択肢をまとめる) 場合、"(" の後に "?" を続けます。\<数字> の記法は、そのパターンの外で使える場合もあるかもしれませんが、これに頼っ てはなりません。括弧は、好きなだけ使ってかまいません。10 個以上の部分文 字列は、$10,$11 などで参照することができます。そのパターンの中では、後方 参照の前に最低限、参照している番号の数だけの開き括弧があれば、\10, \11 などで参照できます。その番号の数だけの開き括弧が無い場合には、(以前のバー ジョンとの互換性のために) \10 は、\010 (バックスペース)、\11 は \011 (タ ブ) といった意味になります。(\1 から \9 は、常に後方参照を意味します。)

$+ は、最後の括弧対にマッチしたものを返します。$& は、マッチした文字列全 体を返します。(以前は、$0 がこの意味に使われましたが、現在は使えません。) $` は、マッチした文字列の前にあったものを返します。$' は、マッチした文字 列の後にあったものを返します。例:

s/^([^ ]*) *([^ ]*)/$2 $1/;     # 最初の 2 語を入替える

if (/Time: (..):(..):(..)/) {
    $hours = $1;
    $minutes = $2;
    $seconds = $3;
}

Perl におけるすべてのバックスラッシュ付きのメタ文字が、\b,\w, \n といっ た英数字であることにお気付きかもしれません。他のいくつかの正規表現言語と は違って、英数字以外にバックスラッシュ付きの記号はありません。つまり、 \\, \(, \), \<, \>,\{, \} といったものはすべて、メタ文字ではなく、リテラ ル文字として解釈されます。このことによって、パターンとして使いたい文字列 に、メタ文字と解釈される文字が含まれている可能性があるときに、たやすくクォー トすることができるようになっています。単に英数字以外の文字を、すべてクォー トすればよいのです:

$pattern =~ s/(\W)/\\$1/g;

同じことを行なうために、組み込みの関数 quotemeta() を使うこともできます。 マッチ演算子の中でより簡単にメタ文字をクォートするには、

/$unquoted\Q$quoted\E$unquoted/

とすればよいでしょう。

Perl 5 では、正規表現に一貫した拡張構文を定義しています。構文は、括弧の ペアの中に、最初の文字としてクエスチョンマークを置いたものとなっています (これは、Perl 4 では構文エラーです)。クエスチョンマークに続く文字で、拡 張の機能のどれを使うのかを示します。いくつかの拡張が、既にサポートされて います:

(?#text)
コメント。Text は無視されます。
(?:regexp)
これは、"()" と同じようにグループ化を行ないますが、"()" のように後方参照 を生成しません。つまり
split(/\b(?:a|b|c)\b/)
は、
split(/\b(a|b|c)\b/)
と似ていますが、余分なフィールドを作りません。
(?=regexp)
長さの無い、前方参照位置指定子。たとえば、/\w+(?=\t)/ は、後ろにタブが続 く単語にマッチしますが、そのタブは $& には含まれません。
(?!regexp)
長さの無い、前方参照否定位置指定子。たとえば、/foo(?!bar)/ は、後ろに "bar" が続かない "foo" にマッチします。前方参照と後方参照は、同じではな いことに注意してください。この構文を後方を参照するために使うことはできま せん。/(?!foo)bar/ では、"foo" 以外のものに続く "bar" を見つけるものでは ありません。(?!foo) は次にくるものが "foo" でないとだけ言っているからで、 次が "bar" であれば、当然"foo" ではありませんから、"foobar" がマッチしま す。先の目的のためには、/(?!foo)...bar/ のように書かなくてはならないでしょ う。「ように」といったのは、"bar" の前に 3 文字無い場合もあるだろうから です。これもカバーするには、/(?:(?!foo)...|^..?)bar/ というように書ける でしょう。単に:
if (/foo/ && $` =~ /bar$/)
と書いた方が簡単なこともあります。 (訳注: これは if(/bar(?=foo)/) かな。($' を除く))
(?imsx)
パターンマッチ修飾子の埋め込み。これは、パターンが、どこかの表に示され、 そのうちのいくつかは大文字小文字を区別せず、いくつかは区別するといった場 合に便利です。区別するものでは、単にパターンの先頭に (?i) を付け加えれば よいのです。たとえば:
$pattern = "foobar";
if ( /$pattern/i )

# パターンに埋め込めば、より柔軟:

$pattern = "(?i)foobar";
if ( /$pattern/ )

この構文や新しい最短一致の構文にクエスチョンマークを選らんだのは、1) 以 前の正規表現においてクエスチョンマークが使われることが少なかったこと、2) これを見つけた人は「疑問」に思ってなにが起こるのかを考えるべきだというこ とによります。これこそ、心理学 ...


Go to the first, previous, next, last section, table of contents.

検索式: