perlre - Perl 正規表現
このページでは Perl での正規表現の構文について説明します。
もしこれまでに正規表現を使ったことがないのであれば、 perlrequick にクイックスタートが、perlretut に 長めのチュートリアルがあります。
正規表現をマッチング操作でどのように使うかやそれに関する様々な例に
関しては、Regexp Quote-Like Operators in perlop にある
m//
, s///
, qr//
, ??
の説明を参照して下さい。
マッチング操作には様々な修飾子(modifier)があります。 修飾子は正規表現内の解釈に関連する物で、次に一覧にしています。 Perl が正規表現を使う方法を変更する 修飾子は Regexp Quote-Like Operators in perlop 及び Gory details of parsing quoted constructs in perlop に 説明されています。
文字列を複数行として扱います。 つまり、"^" 及び "$" は文字列の最初と最後に対するマッチングから、 文字列中の各行の先頭と末尾に対するマッチングへと変更されます。
文字列を 1 行として扱います。 つまり、"." は任意の 1 文字、通常はマッチングしない改行でさえも マッチングするように変更されます。
/ms として共に使うと、"^" 及び "$" はそれぞれ 文字列中の改行の直前及び直後のマッチングでありつつ、"." は任意の文字に マッチングするようになります。
大文字小文字を区別しないパターンマッチングを行います。
use locale
が有効になっている場合には大文字小文字の対応表は
現在のロケールから取られます。
perllocale を参照してください。
空白やコメントを許可してパターンを読みやすくするように拡張します。
${^PREMATCH}, {$^MATCH}, ${^POSTMATCH} といったマッチングされた 文字列をマッチングの後も使えるように維持します。
グローバル(Global)なマッチング、及びマッチング失敗後の 現在位置の保持。 i, m, s, x とは違い、この二つのフラグは 正規表現そのものではなく正規表現の使われ方に作用します。 g 及び c 修飾子の詳細な説明は Using regular expressions in Perl in perlretut を参照してください。
これらは通常「/x
修飾子」のように記述され、これは区切りがスラッシュで
なくてもそう記述されます。
また、これらはいずれも (?...)
構築子を使って正規表現内に
埋め込まれることもあります。
/x
に関してはもう少し説明が必要です。
これはバックスラッシュでエスケープされているか文字クラスの中にあるか以外の
空白文字を無視するように正規表現パーサに伝えます。
これを使うことで正規表現を(若干)より読みやすいパーツに分解できます。
そして #
文字は通常の Perl コードのようにコメントを始めるメタ文字として
扱われるようになります。
これはパターンの中(それも /x
の影響を受けない文字クラスの外)で実際に
空白や #
文字を必要とするときには、エスケープするか 8 進数もしくは
16 進数エスケープ(バックスラッシュもしくは \Q...\E
)を
しなければなりません。
/x
でこれらの機能を利用することで、Perl の正規表現をより
読み易くするのに非常に役立ちます。
ただ、コメントの中にパターン区切り子を書いてしまわないようには
注意してください -- perl にはパターンを早めに終わらせようとした
訳ではないことを知る方法がないのです。
C スタイルのコメントを削除するコードは perlop を参照してください。
また \Q...\E
の内側になる箇所は /x
の影響を受けないことに
注意してください。
Perl のパターンマッチングで使われるパターンは Version 8 正規表現ルーチンで 提供されているものからの派生です。 (このルーチンは Henry Spencer の自由に再配布可能な V8 ルーチンの再実装から (遠く)派生しています)。 詳細は バージョン 8 正規表現 を参照してください。
特に以下のメタ文字は標準の egrep 風の意味を持っています:
\ 次のメタ文字をエスケープ ^ 行の先頭にマッチング . 任意の文字にマッチング(但し改行は除く) $ 行の終端にマッチング(または終端の改行の前) | 代替 () グループ化 [] 文字クラス
デフォルトでは、文字 "^" は文字列の先頭にのみ、そして文字 "$" は
末尾(または末尾の改行の前)にのみマッチングすることを保証し、そして Perl は
文字列が 1 行のみを含んでいるという仮定でいくつかの最適化を行います。
埋め込まれている改行文字は "^" や "$" とはマッチングしません。
しかし文字列には複数行が格納されていて、"^" は任意の改行の後(但し
改行文字が文字列の最後の文字だった場合は除く)、そして "$" は任意の改行の前で
マッチングさせたいこともあるでしょう。
小さなオーバーヘッドはありますが、これはパターンマッチングで /m 修飾子を
使うことで行うことができます。
(古いプログラムでは $*
を設定することでこれを行っていましたが
これは perl 5.9 では削除されています。)
複数行での利用を簡単にするために、文字 "." は /s
修飾子を
使って Perl に文字列を1行として処理すると伝えない限り
改行にはマッチングしません。
以下の標準的な量指定子を使えます:
* 0 回以上のマッチング + 1 回以上のマッチング ? 1 回または 0 回のマッチング {n} ちょうど n 回のマッチング {n,} n 回以上のマッチング {n,m} n 回以上 m 回以下のマッチング
(これ以外のコンテキストで波かっこが使われたときには普通の文字として
使われます。
また、下限は省略可能ではありません。)
"*" 量指定子は {0,}
と、"+" 量指定子は {1,}
と、
"?" 量指定子は {0,1}
と等価です。
n 及び m は perl をビルドしたときに定義した既定の制限より小さな整数回に
制限されます。
これは大抵のプラットフォームでは 32766 回になっています。
実際の制限は次のようなコードを実行すると生成されるエラーメッセージで
見ることができます:
$_ **= $_ , / {$_} / for 2 .. 42;
デフォルトでは、パターンで行われる量指定は"貪欲"です; つまりそれはパターンの残りの部分が可能な範囲で、 (始めた地点から)可能な限り多くを先にあるパターンでマッチングさせます。 もし最小回数でのマッチングを行いたいのであれば、量指定子の後ろに "?" を続けます。 意味は変更されずに「貪欲さ」だけを変更できます:
*? 0 回以上の貪欲でないマッチング +? 1 回以上の貪欲でないマッチング ?? 0 回または 1 回の貪欲でないマッチング {n}? ちょうど n 回の貪欲でないマッチング {n,}? n 回以上の貪欲でないマッチング {n,m}? n 回以上 m 回以下の貪欲でないマッチング
デフォルトでは、パターンのうちの量指定された一部によってパターン全体が マッチングに失敗したとき、Perl はバックトラックを行います。 しかしこの振る舞いは望まれないこともあります。 そのため、Perl は「絶対最大量(possessive)」量指定形式も提供しています。
*+ 0 回以上のマッチングでなおかつ全く戻らない ++ 1 回以上のマッチングでなおかつ全く戻らない ?+ 0 回または 1 回のマッチングでなおかつ全く戻らない {n}+ ちょうど n 回のマッチングでなおかつ全く戻らない (冗長) {n,}+ n 回以上のマッチングでなおかつ全く戻らない {n,m}+ n 回以上 m 回以下のマッチングでなおかつ全く戻らない
例えば,
'aaaa' =~ /a++a/
は、a++
が文字列中の全ての a
を飲み込んで
しまい後に何も残さないためマッチングしません。
この機能はバックトラックするべきでない場所のヒントを perl に
与えるのに非常に便利です。
例えば、典型的な「ダブルクォート文字列のマッチング」問題で次のように
書くととても効率的になります:
/"(?:[^"\\]++|\\.)*+"/
見ての通り最後のクォートがマッチングしなかったとき、バックトラックは
役に立ちません。
詳細は独立したサブパターン (?>...)
を参照してください;
絶対最大量指定子はまさにその構文糖です。
例えばこの例は次のようにも書けます:
/"(?>(?:(?>[^"\\]+)|\\.)*)"/
パターンはダブルクォート文字列として処理されるため、 以下のエスケープ文字も動作します:
\t タブ (水平タブ;HT、TAB) \n 改行 (LF、NL) \r 復帰 (CR) \f フォームフィード (FF) \a アラーム (ベル) (BEL) \e エスケープ (troff 的) (ESC) \033 8進文字 (例: ESC) \x1B 16進文字 (例: ESC) \x{263a} ロング16進文字 (例: Unicode SMILEY) \cK 制御文字 (例: VT) \N{name} 名前付きユニコード文字 \l 次の文字を小文字に (vi 的) \u 次の文字を大文字に (vi 的) \L \E まで小文字に (vi 的) \U \E まで大文字に (vi 的) \E 変更の終端 (vi 的) \Q \E までパターンメタ文字の無効化(Quote)
use locale
の影響下であれば、\l
, \L
, \u
, \U
による大文字小文字変換は現在のロケールで処理されます。
perllocale を参照してください。
\N{name}
に関するドキュメントは charnames を参照してください。
\Q
シーケンス内であっても $
及び @
のリテラルは
含めることはできません。
エスケープされていない $
及び @
は対応する変数の埋め込みとなり、
とはいえエスケープは リテラル文字列 \$
とのマッチングになります。
m/\Quser\E\@\Qhost/
といった感じに記述する必要があります。
加えて、Perl は以下のものを定義しています:
\w "単語" 文字にマッチング (英数字及び"_") \W 非"単語"文字にマッチング \s 空白文字にマッチング \S 非空白文字にマッチング \d 数字にマッチング \D 非数字にマッチング \pP 名前属性 P にマッチング. 長い名前であれば \p{Prop}. \PP P以外にマッチング \X 拡張 Unicode "複合文字シーケンス (combining character sequence)" のマッチング、(?>\PM\pM*)と等価 \C 1つの C 文字 (オクテット)にマッチング、Unicode 環境でも同じ 補足: 文字をUTF-8バイト列へと変換するので、壊れた UTF-8 片となるかもしれません. 後読みはサポートしていません \1 指定したグループへの後方参照 '1' には正の整数を指定できます \g1 指定したまたは前のグループへの後方参照 \g{-1} 数値は前のバッファを示す負の値にもできます、また 任意で安全にパースするために波かっこで括ることもできます \g{name} 名前指定の後方参照 \k<name> 名前指定の後方参照 \K \K の左にある物を保持、$& に含めない \v 垂直空白 \V 垂直空白以外 \h 水平空白 \H 水平空白以外 \R 行区切り
\w
は単語全体ではなく、1つの英数字(アルファベットまたは数字)または
_
にマッチングします。
Perl で識別子となる文字列(これは英単語とは異なります)に
マッチングさせるためには \w+
を使います。
use locale
の影響下であれば、\w
で適用されるアルファベットは
現在のロケールから採用されます。
perllocale を参照してください。
\w
, \W
, \s
, \S
, \d
, そして \D
は文字クラスでも
利用できますが、範囲の両端には使えません。
その前後に "-" を使ったとき、その "-" はリテラルとして処理されます。
もし Unicode 環境下であれば \s
は "\x{85}", "\x{2028}", "\x{2029}" にも
マッチングします。
\pP
, \PP
, 及び \X
の詳細と独自の \p
及び \P
属性を
定義することに関しては perlunicode を、そして Unicode 一般に関しては
perluniintro を参照してください。
\R
はネットワーク行末 "\x0D\x0A" を含めた
行区切りにアトミックにマッチングします。
本質的に、\R
は次と等価です。
(?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}])
補足: \R
は文字クラスでは特別な意味を持ちません;
代わりに \v
(垂直空白)を利用してください)。
POSIX 文字クラス構文
[:class:]
も利用可能です。
[
及び ]
ブラケットは
リテラルという点に注意してください; これらは
文字クラス式の中で常に使う必要があります。
# this is correct: $string =~ /[[:alpha:]]/;
# this is not, and will generate a warning: $string =~ /[:alpha:]/;
利用可能な文字クラスとそれと等価な バックスラッシュ記法(提供されていれば)は以下の通りです:
alpha alnum ascii blank [1] cntrl digit \d graph lower print punct space \s [2] upper word \w [3] xdigit
[ \t]
と等価な GNU 拡張、「全ての水平空白」。
[[:space:]]
には(とても稀な)「垂直タブ」, "\cK" または
ASCII での chr(11) が含まれるため \s
と完全な等価ではありません。
Perl 拡張、上述の通り。
例えば全ての大文字にマッチングさせるためには [:upper:]
を
使うことができます。
[]
は [::]
構成子の一部であって、完全な文字クラスの一部ではありません。
例えば:
[01[:alpha:]%]
は, 0, 1, 任意の英字、そしてパーセント記号にマッチングします。
以下の Unicode \p{} 構成子及び等価なバックスラッシュ 文字クラス(提供されていれば)の等式:
[[:...:]] \p{...} backslash
alpha IsAlpha alnum IsAlnum ascii IsASCII blank cntrl IsCntrl digit IsDigit \d graph IsGraph lower IsLower print IsPrint (but see [2] below) punct IsPunct (but see [3] below) space IsSpace IsSpacePerl \s upper IsUpper word IsWord \w xdigit IsXDigit
例えば [[:lower:]]
と \p{IsLower}
は等価です。
しかし、[[:xxxxx:]]
および \p{IsXxxxx}
の等価性は正確ではありません。
utf8
プラグマは使われていなくて locale
プラグマが
使われていた場合にはクラスは通常の isalpha(3)
インターフェースと
相互に関連します(但し "word" 及び "blank" は除く)。
しかし、もし locale
プラグマや encoding
プラグマが使われておらず、
文字列が utf8
でないなら、[[:xxxxx:]]
(および \w
など) は
文字 0x80-0xff にマッチングしません; 一方 \p{IsXxxxx}
は文字列を
utf8
に強制して、これらの文字に (Unicode として)マッチングします。
\p{IsPrint}
は文字 0x09-0x0d にマッチングしますが [[:print:]]
は
マッチングしません。
[[:punct::]]
は以下の物にマッチングしますが \p{IsPunct}
は
マッチングしません; なぜならこれらは Unicode では (句読点ではなく)
シンボルにクラス分けされるからです。
$
通貨記号
+
<
=
>
|
~
算術記号
^
`
修飾シンボル (アクセント)
その他の名前付きクラスは以下の通りです:
任意の制御文字。
通常出力を生成する代わりにターミナルの制御を行う文字: 例えば改行や
バックスペースは制御文字です。
ord()
が 32 未満となる全ての文字は制御文字として
分類され(ASCII、ISO ラテン文字集合、及び Unicode を仮定)、
ord()
が値 127 となる文字(DEL
)も同様です。
全ての英数字及び句読点(特殊)文字。
全ての英数字、句読点(特殊)文字、及び空白文字。
全ての句読点(特殊)文字。
全ての 16 進数字。 これはばかばかしいと感じるかもしれませんが([0-9A-Fa-f] もちゃんと 動作します)、完全性のために含まれています。
クラス名の前に '^' をおくことで [::] 文字クラスの補集合を使うこともできます。 これは Perl での拡張です。 例:
POSIX traditional Unicode
[[:^digit:]] \D \P{IsDigit} [[:^space:]] \S \P{IsSpace} [[:^word:]] \W \P{IsWord}
Perl は POSIX 文字クラスにある POSIX 標準は文字クラスのみを サポートしていると考えます。 POSIX 文字クラス [.cc.] 及び [=cc=] は認識されますが、 サポートはされておらずそれを使うとエラーとなるでしょう。
Perl は以下のゼロ幅のアサーションを定義しています:
\b 単語境界にマッチング \B 単語境界以外にマッチング \A 文字列の開始にのみマッチング \Z 文字列の終端または終端の改行前にのみマッチング \z 文字列の終端にのみマッチング \G pos() の位置にのみマッチング (つまり前のm//gのマッチング終端位置)
単語境界(\b
)は\W
にマッチングする文字列の始まりと終わりを
連想するような、片側を \w
、もう片側を \W
で挟まれている点です。
(文字クラスにおいては \b
は単語境界ではなくバックスペースを表します,
ちょうどダブルクォート文字列と同じように。)
\A
及び \Z
は "^" 及び "$" と同様ですが、/m
修飾子が
指定されているときに "^" 及び "$" は全ての内部的な行境界に
マッチングするのに対して \A
及び \Z
は複数回のマッチングには
なりません。
文字列の本当の末尾にマッチングさせ、省略可能である末尾の改行を
無視しないようにする \z
を使います。
\G
アサーションはグローバルなマッチング(m//g
)を連結するために
使います; これは Regexp Quote-Like Operators in perlop にも説明されています。
これは文字列に対していくつかのパターンを次々にマッチングさせたいといった、
lex
風のスキャナを書きたいときにも便利です; 同じリファレンスを
参照してください。
\G
が実際にマッチングできる位置は pos()
を左辺値として
使うことで変更できます: pos in perlfunc を参照してください。
ゼロ幅マッチングのルールは少し変化することに注意してください、
\G
の左にある内容はマッチングの長さを決定するときに
数えられません。
従って次のコードは永遠にマッチングしません:
$str = 'ABC'; pos($str) = 1; while (/.\G/g) { print $&; }
これはゼロ幅へのマッチングと見なされ、'A' を出力し終了するので、 行の中で同じ場所に二度はマッチングしません。
適切に使われていない \G
は無限ループとなり何の価値もありません。
代替(alternation; |
)の中に \G
を含んでいるパターンを使う際には
十分注意してください。
( ... )
を構成するブラケットは捕捉バッファを生成します。
同じパターンの後方で内容を参照するには、最初のものであれば \1 を、
2 番目のものであれば \2 を使います。
マッチングの外側では "\" の代わりに "$" を使います。
(\<数字> 記法はマッチングの外側でも特定の状況では動作します。
\1 と $1 に関する警告の詳細は後述を参照してください。)
マッチングの別の部分を戻って参照することは、後方参照 (backreference)と
呼ばれます。
使用できるキャプチャされた部分文字列の数に制限はありません。 しかし Perl は \10, \11 などを \010, \011 などの別名として使います。 (0 は 8 進数を意味することを思い出してください; つまり \011 はあなたの コーディングしている文字集合での番号 9 にあたる文字になります; これは 10 番目の文字であり、ASCII においては水平タブになります。) Perl はこれを両方の意味で解釈し、少なくとも 10 の左かっこが使われていれば \10 を後方参照として解釈します。 同じように 11 の左かっこがあれば \11 を後方参照として解釈します。 その先も同様です。 \1 から \9 は常に後方参照として解釈されます。
後方参照を使ったパターンをより安全で簡単に構成するために、
Perl は \g{N}
記法を提供します(5.10.0 以降)。
波かっこは任意ですが、省略するとそれに続くテキストが変わると(つまり数字が
続く場合に)安全ではなくなります。
N が正の整数のとき、\g{N}
は通常の後方参照とちょうど同じです。
N が負の整数の時、N 個前の捕捉グループを参照する相対的な後方参照になります。
ブラケット形式で N が整数でないときは名前付きバッファへの参照として
扱われます。
従って \g{-1}
は最後のバッファを、\g{-2}
はその前のバッファを
参照します。
例えば:
/ (Y) # buffer 1 ( # buffer 2 (X) # buffer 3 \g{-1} # backref to buffer 3 \g{-3} # backref to buffer 1 ) /x
は /(Y) ( (X) \3 \1 )/x
と同じマッチングとなります。
加えて、5.10.0 時点では名前付き捕捉バッファ及び名前付き後方参照を
利用できます。
(?<name>...)
で宣言し、\k<name>
で参照します。
名前区切りに各かっこの代わりにアポストロフィを使うこともできます;
そしてブラケットによる \g{name}
後方参照構文を使うこともできます。
名前付き捕捉バッファを通常通りに絶対及び相対番号で参照することもできます。
パターンの外においては、名前付き捕捉バッファは %+
ハッシュを通して
利用できます。
同じパターン内で異なるバッファが同じ名前を持っていたとき、$+{name}
及び \k<name>
は一番左で定義されたグループを参照します。
(つまり処理のために C(<??{})> を必要とする別の方法の名前付き捕捉バッファで
行うこともできます.)
>>
例:
s/^([^ ]*) *([^ ]*)/$2 $1/; # swap first two words
/(.)\1/ # find first doubled char and print "'$1' is the first doubled character\n";
/(?<char>.)\k<char>/ # ... a different way and print "'$+{char}' is the first doubled character\n";
/(?'char'.)\1/ # ... mix and match and print "'$1' is the first doubled character\n";
if (/Time: (..):(..):(..)/) { # parse out values $hours = $1; $minutes = $2; $seconds = $3; }
いくつかの特殊変数もまた以前のマッチングの一部を参照しています。
$+
は最後のマッチングしたブラケットマッチングと返します。
$&
はマッチングした文字列全体を返します。
(一頃は $0
もそうでしたが、現在ではこれはプログラム名を返します。)
$`
はマッチングした文字列の前の全てを返します。
$'
はマッチングした文字列の後の全てを返します。
そして $^N
には一番最後に閉じたグループ(サブマッチング)に
マッチングしたものを含んでいます。
$^N
は例えばサブマッチングを変数に格納するため等に拡張パターンの中でも
利用できます(後述)。
数値によるマッチング変数($1, $2, $3 など)及び関連する記号変数
($+
, $&
, $'
, $^N
)はすべてブロックの終端または次のマッチング
成功までのどちらか先に満たした方の、動的なスコープを持ちます。
(Compound Statements in perlsyn を参照してしてください。)
補足: Perl において失敗したマッチングはマッチング変数をリセットしません; これはより特殊化させる一連のテストを書くことや、 最善のマッチングを書くことを容易にします。
警告: Perl は、一旦プログラム中のどこかで $&
, $`
, $'
の
いずれかを必要としていることを見つけると、全てのパターンマッチングで
それらを提供しなければなりません。
これはあなたのプログラムを大幅に遅くさせるでしょう。
Perl は $1, $2, 等の生成にも同じメカニズムを使っているので、
キャプチャのかっこに含まれるそれぞれのパターンにも
同じ料金を払っています。
(グループ化の振る舞いを維持しつつこのコストを削減するには
拡張正規表現 (?: ... )
を代わりに使います。
(訳注:Perl拡張というだけで /x
修飾子は不要。))
ですが $&
, $`
または $'
を一度も使わなければ、
キャプチャのかっこをもたないパターンではこの不利益はなくなります。
この為、可能であれば $&
, $'
, 及び $`
を削除しましょう:
しかしそれができなかった(そしてそれらを
本当に理解しているアルゴリズムがあるのであれば)、一旦
それらを使った時点でそれ以降は自由にそれらを使うことができます;
なぜならあなたは(一度使った時点で)既に代価を払っているので。
5.005 であれば $&
は他の2つほど高価ではありません。
この問題に対する解決策として、Perl 5.10.0 からは $`
, $&
, $'
と
等価だけれども /p
(preseve) 修飾子を伴って実行されたマッチングが
成功した後でのみ定義されることが保証される ${^PREMATCH}
、
${^MATCH}
及び ${^POSTMATCH}
を導入しました。
これらの変数の使用は利用したいときに perl に伝える必要がある代わりに、
等価な記号変数とは違い全体的なパフォーマンスの低下を引き起こしません。
Perl においてバックスラッシュで表現されるメタ文字は \b
, \w
,
\n
のように英数字です。
他の正規表現言語とは異なり、英数字でないシンボルのバックスラッシュは
ありません。
なので \\, \(, \), \<, \>, \{, \} といったものは全てメタ文字ではなく
リテラル文字です。
これはパターンで使いたい文字列の中で正規表現のメタ文字としての特殊な意味を
無効化またはクォートするための一般的な指標として使われてきました。
「単語」でない全ての文字は単にクォートします:
$pattern =~ s/(\W)/\\$1/g;
(もし use locale
が有効であれば、これは現在のロケールに依存します。)
今日では特殊な意味を持つメタ文字を全て無効にするためには次のように
quotemeta()
関数か \Q
メタクォートエスケープシーケンスを使うのが
より一般的です:
/$unquoted\Q$quoted\E$unquoted/
\Q
及び \E
の間でリテラルとしてバックスラッシュをおくとき
(埋め込んだ変数の中でではない)には、二重にクォートしたバックスラッシュの
埋め込みは困惑した結果となるでしょう。
もし \Q...\E
でリテラルとしてのバックスラッシュを使う
必要がある のなら、
Gory details of parsing quoted constructs in perlop を参照してください。
Perl は awk や lex といった標準的なツールでは見られない機能のための 拡張構文も定義しています。 構文は対のかっことかっこ内の最初に疑問符の形をとります。 疑問符の後の文字で拡張を区別します。
拡張構文の安定度は様々です。 中には長年言語コアの一部となっている物もあります。 そうでなく実験的に追加され警告なしに変更されたり削除されるものも 中にはあります。 それぞれのステータスに関しては個々の機能のドキュメントを確認してください。
疑問符は 1) それが古い正規表現で使われることは稀であること、そして 2) それを見かけると何が行われるのか本当に「疑問に」思って止まることから、 これのためと最小マッチング構成子のために選ばれました。
(?#text)
コメント。
テキストは無視されます。
/x
修飾子によって空白の整形が有効にされていれば単なる #
でも十分です。
Perl は )
を見つけると直ぐにコメントを閉じる点に注意してください;
この為リテラル )
をコメント中におくことはできません。
(?pimsx-imsx)
一つもしくは複数のパターンマッチング修飾子;
パターンの残りまたは(もしあれば)包含しているパターングループの残りで
有効にする(または -
が前置されていれば解除する)。
これは設定ファイルから読む、引数から取る、どこかのテーブルで
指定されている箇所からダイナミックなパターンを使うときに特に便利です。
パターンの一部では大文字小文字を区別したいけれども別の箇所では
区別しないといったケースを考えてみます: 区別をしない場所では
単にパターンの先頭に (?i)
を含めるだけです。
例えば:
$pattern = "foobar"; if ( /$pattern/i ) { }
# more flexible:
$pattern = "(?i)foobar"; if ( /$pattern/ ) { }
これらの修飾子は包含しているグループの最後で復元(restore)されます。 例えば、
( (?i) blah ) \s+ \1
は blah
に大文字小文字の区別なくマッチングし、
いくつかの空白、そして前の単語その物(大文字小文字の区別まで含めて!)に
再度マッチングします; ここではこのグループの外側で /x
修飾子を持ち、
/i
修飾子を持たないものとします。
p
修飾子は有効にできるのみで、無効にはできない点、そして
パターンのどこかにあればパターン全体で有効になる点で特別です。
従って (?-p)
及び (?-p:...)
は意味を持たず、use warnings
の下では
警告を発します。
(?:pattern)
(?imsx-imsx:pattern)
これはキャプチャではなくクラスタです; これは "()" のように部分式を グループ化しますが "()" が行うような後方参照は行いません。 つまり、
@fields = split(/\b(?:a|b|c)\b/)
は次と同様ですが
@fields = split(/\b(a|b|c)\b/)
余計なフィールドを引き出しません。 また不要であれば文字のキャプチャを行わないため低コストです。
?
及び :
の間の文字は (?imsx-imsx)
のようなフラグ修飾子として
動作します。
/(?s-i:more.*than).*million/i
はより冗長に書けば以下と等価です
/(?:(?s-i)more.*than).*million/i
(?|pattern)
これは各代替分岐において捕捉バッファを同じ番号から始める特殊な 属性を持っている、「ブランチリセット(branch reset)」パターンです。 これは perl 5.10.0 から提供されています。
捕捉バッファは左から右へと番号が振られますが、この構成子の内側では 各分岐毎に番号はリセットされます。
各分岐内での番号付けは通常通りに行われ、この構成子の後に続くバッファは その中で捕捉バッファが一番多かった分岐のみが 格納されていたかのように番号付けされていきます。
この構成子はいくつかの代替マッチングの1つを捕捉したいときに便利です。
以下のパターンを想像してみてください。 下側の番号は内容の格納されるバッファを示します。
# before ---------------branch-reset----------- after / ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x # 1 2 2 3 2 3 4
補足: Perl 5.10.0 時点では、ブランチリセットは
名前付きキャプチャを保持する%+
ハッシュの内容に干渉します。
%-
を使うようにしてください。
先読み及び後読みの言明(assertion)は $&
の中に
含めない特定のパターンにマッチングするゼロ幅のパターンです。
正の言明はその部分パターンがマッチングしたときにマッチングし、
負の言明はその部分パターンが失敗したときにマッチングします。
後読みのマッチングは今のマッチング位置までのテキストにマッチングし、
先読みの言明は今のマッチング位置の先にあるテキストにマッチングします。
(?=pattern)
ゼロ幅の正の先読み言明。
例えば、/\w+(?=\t)/
はタブが続く単語にマッチングしますが、タブは
$&
に含まれません。
(?!pattern)
ゼロ幅の負の先読み言明。
例えば /foo(?!bar)/
は "bar" が続かない全ての "foo" にマッチングします。
しかしながら先読みと後読みは同じ物では ない点に注意してください。
これを後読みに使うことはできません。
もし "foo" が前にない "bar" を探しているのなら、
/(?!foo)bar/
では欲しい物にはなりません。
なぜなら (?!foo)
は次のものが "foo" ではないとだけいっているのです --
そしてそうではなく、そこには "bar" があるので、"foobar" はマッチングします。
このような時には /(?!foo)...bar/
のような形で使う必要があるでしょう。
ここで "ような" といっているのは "bar" が場合によっては
3 文字ではないこともあるからです。
次のようにしてこれをカバーすることができます:
/(?:(?!foo)...|^.{0,2})bar/
。
またもっと簡単に次のようにできることもあるでしょう:
if (/bar/ && $` !~ /foo$/)
後読みは以下を参照。
(?<=pattern)
\K
ゼロ幅の正の後読みの言明。
例えば、/(?<=\t)\w+/
は
タブに続く単語にマッチングしますが、タブは $& に 含まれません。
固定幅の後読みのみが動作します。
\K
というこの構成子の特殊な形式もあります、
これは正規表現エンジンに対してそれが \K
までにマッチングした
すべてのものを"取っておいて"、$&
には含めないようにさせます。
これは事実上可変長の後読みを提供します。
他の先読み及び後読みの言明の中での利用も可能ですが、その振る舞いは
今のところあまり定義されていません。
いくつかの理由から、\K
は等価な (?<=...)
構成子より非常に効率的で、文字列の中で何かに続いている何かを効率的に
取り除きたいようなシチュエーションで効果的に役立ちます。
例えば
s/(foo)bar/$1/g;
次のようにより効率的に書き直せます
s/foo\Kbar//g;
(?<!pattern)
ゼロ幅の負の後読みの言明。
例えば /(?<!bar)foo/
は "bar" に続いていない任意の "foo" に
マッチングします。
固定幅の後読みのみが動作します。
(?'NAME'pattern)
(?<NAME>pattern)
) >>名前付の捕捉バッファ。
通常のキャプチャかっこ ()
と同様ですがそれに加えて
成功したマッチングの後で名前付バッファを参照するために %+
もしくは
%-
を使うことが出来ます。
%+
及び %-
ハッシュに関する詳細は perlvar を
参照してください。
複数の異なる捕捉バッファが同じ名前を持っていたときには $+{NAME} はマッチングの中で一番左で定義されたバッファを参照します。
二つの形式 (?'NAME'pattern)
及び (?<NAME>pattern)
は等価です。
補足: これを構成する記法は 類似していている .NET での正規表現と 同じですが、振る舞いは異なります。 Perl ではバッファは名前がついているかどうかにかかわらず順番に番号が 振られます。 従って次のパターンにおいて
/(x)(?<foo>y)(z)/
$+{foo} は $2 と同じであり、$3 には .NET 正規表現に 慣れた人が予測するのとは異なり 'z' が含まれます。
現在のところ NAME はシンプルな識別子のみに制限されています。
言い換えると、/^[_A-Za-z][_A-Za-z0-9]*\z/
または
その Unicode 拡張にマッチングしなければなりません
(utf8 も参照); しかしロケールでは拡張されません
(perllocale 参照)。
補足: Python や PCRE 正規表現エンジンになれたプログラマが
楽になるように、(?<NAME>pattern)
の代わりに
(?P<NAME>pattern)
のパターンを使うことも
できます; しかしこの形式は名前のデリミタとして
シングルクォートの使用はサポートされていません。
\k<NAME>
\k'NAME'
名前による後方参照。 数値によってではなく名前によってグループを指定する点を除いて、名前による 後方参照と似ています。 もし同じ名前の複数のグループがあったときには現在のマッチングで 一番左に定義されているグループを参照します。
パターン内で (?<NAME>)
によって定義されていない名前を
参照するとエラーになります。
両方の形式とも等価です。
補足: Python や PCRE 正規表現エンジンになれたプログラマが楽に
なるように、\k<NAME>
の代わりに
(?P=NAME)
のパターンを使うこともできます。
(?{ code })
警告: この拡張正規表現の機能は実験的なものと考えてください、 また追う通知なしに変更されるかもしれません。 副作用を持つコードの実行は今後の正規表現エンジンの最適化の影響で バージョン間で必ずしも同じになるとは限らないでしょう。
このゼロ幅アサーションは埋め込まれた任意の Perl コードを評価します。
これは常に(正規表現として)成功し、その code
は埋め込まれません。
今のところ、code
が終わる場所を認識するルールは少々複雑です。
この機能では一緒にネストしたかっこの数を数えなくとも1つ前の
マッチング結果をキャプチャ特殊変数 $^N
を使うことができます。
$_ = "The brown fox jumps over the lazy dog"; /the (\S+)(?{ $color = $^N }) (\S+)(?{ $animal = $^N })/i; print "color = $color, animal = $animal\n";
(?{...})
ブロックの中では $_
は正規表現をマッチングさせている文字列を
参照します。
pos()
を使ってこの文字列で現在のマッチング位置を知ることもできます。
code
は次の感じで適切にスコープを持ちます: もしアサーションが
バックトラックされている(バックトラック 参照)のなら、
local
されなかった後の全ての変更、つまり
$_ = 'a' x 8; m< (?{ $cnt = 0 }) # Initialize $cnt. ( a (?{ local $cnt = $cnt + 1; # Update $cnt, backtracking-safe. }) )* aaaa (?{ $res = $cnt }) # On success copy to non-localized # location. >x;
は $res = 4
を設定します。
マッチングの後で $cnt
はグローバルに設定された値を返します; なぜなら
local
演算子で制限されたスコープは巻き戻されるためです。
このアサーションは (?(condition)yes-pattern|no-pattern)
スイッチとして
使われるかもしれません。
この方法で使われなかったのなら、code
の評価結果は特殊変数 $^R
に
おかれます。
これはすぐに行われるので $^R
は同じ正規表現内の他の $?{ code })
アサーションで使うことができます。
この $^R
への設定は適切にlocal化されるため、$^R
の古い値は
バックトラックしたときには復元されます; バックトラック を
見てください。
不運にも実装上の理由によりこれらのブロックに含まれる Perl コードは 関数やループ内でレキシカルスコープな変数とともに使うと 一見奇妙な結果を持つコンパイル時のクロージャとして扱われます。 これの対処方法は、単純にに代わりにグローバル変数を使うことも含めて 幾つかあります。 もしこの構成子を使って奇妙な結果が発生しているのなら、レキシカルスコープな 変数を使っているかどうかを確認してみてください。
セキュリティ的な理由により、正規表現を実行時に変数から構築することは、
危険な use re 'eval'
プラグマが使われている(re 参照)か
変数が qr//
演算子(qr/STRING/imosx in perlop 参照)の結果を
含んでいる時以外は拒否されます。
この制限は、実行時に決まる文字列をパターンとして使う、とても広まっていて とても便利な風習のためのものです。 例えば:
$re = <>; chomp $re; $string =~ /$re/;
Perl がパターンの中にあるコードを実行する方法を知る前はこの操作は不正な
パターンで例外を発生させはしますがセキュリティ的な視点で完全に安全でした。
もし use re 'eval'
を有効にしているのなら、これはもはやセキュアでは
ありません; そして汚染チェックを使っているときにだけ行うべきです。
より良い方法としては、Safe の区画内で注意深く制限された評価を
使うべきでしょう。
この双方のメカニズムについての詳細は perlsec を参照してください。
Perl の正規表現エンジンは今のところ再入可能ではないので、埋め込まれた
コードからは m//
または s///
を使って直接的にでも split
のような
関数を使って間接的にでも呼び出さないでください。
(??{ code })
警告: この拡張正規表現の機能は実験的なものと考えられており、 また通知なしに変更されるかもしれません。 副作用を持つコードの実行は今後の正規表現エンジンの最適化の影響で バージョン間で必ずしも同じになるとは限らないでしょう。
これは「先送りされた」正規部分表現です。
code
は実行時に評価され、そのときにこの部分表現にマッチングさせます。
評価の結果は正規表現として受け取られ、この構成子の代わりに
入れられていたかのようにマッチングされます。
これは eval されたパターン内部で定義された捕捉バッファの内容はパターンの
外側では提供されず、そしてその逆も同様になる点に注意してください;
内側のパターンが外側で定義された捕捉バッファを参照する方法はありません。
例えば、
('a' x 100)=~/(??{'(.)' x 100})/
これはマッチング します が、$1 は設定 されません。
code
は埋め込まれません。
先の時と同様に code
が終了していると決定するルールは少々複雑です。
次のパターンはかっこで囲まれたグループにマッチングします:
$re = qr{ \( (?: (?> [^()]+ ) # Non-parens without backtracking | (??{ $re }) # Group with matching parens )* \) }x;
同じタスクを行う別の、より効率的な方法として (?PARNO)
も
参照してください。
Perl の正規表現エンジンは今のところ再入可能ではないので、
遅延されたコードからは m//
または s///
を使って直接的にでも
split
のような関数を使って間接的にでも呼び出さないでください。
入力を消費しない 50 回を超える深い再帰は致命的なエラーとなります。 最大深度は perl にコンパイルされているので、これを変更するには 特別にビルドする必要があります。
(?PARNO)
(?-PARNO)
(?+PARNO)
(?R)
(?0)
コードのコンパイルを伴わなず、その代わりに捕捉バッファの内容を現在の位置で
マッチングすべき独立したパターンとして扱う、(??{ code })
と似た機能です。
パターンに内包されている捕捉バッファは一番外側の再帰として
決定されるという価値があります。
PARNO はその値が再帰させる捕捉バッファのかっこ番号を反映する一連の
数字からなります(そして 0 からは始まりません)。
(?R)
はパターン全体の最初から再帰します。
(?0)
は (?R)
の別の構文です。
PARNO の前に正符号または負符号がついていた場合には相対的な位置として
使われます; 負数であれば前の捕捉バッファを、正数であれば続く
捕捉バッファを示します。
従って (-1)
は一番最近宣言されたバッファを参照し、(?+1)
は次に
宣言されるバッファを参照します。
相対再帰の数え方は相対後方参照とは違って、バッファに閉じていない再帰は
含まれることに注意してください,
以下のパターンは引数にバランスのとれたかっこを含んでいるかもしれない関数
foo()
にマッチングします。
$re = qr{ ( # paren group 1 (full function) foo ( # paren group 2 (parens) \( ( # paren group 3 (contents of parens) (?: (?> [^()]+ ) # Non-parens without backtracking | (?2) # Recurse to start of paren group 2 )* ) \) ) ) }x;
このパターンを以下のように使うと,
'foo(bar(baz)+baz(bop))'=~/$re/ and print "\$1 = $1\n", "\$2 = $2\n", "\$3 = $3\n";
次のように出力されます:
$1 = foo(bar(baz)+baz(bop)) $2 = (bar(baz)+baz(bop)) $3 = bar(baz)+baz(bop)
もし対応する捕捉バッファが定義されていなかったときには致命的な エラーとなります。 入力を消費しない 50 回を超える深い再帰も致命的なエラーとなります。 最大深度は perl にコンパイルされているので、これを変更するには特別に ビルドする必要があります。
以下に後で使うパターンのために、qr//
構成子内で再帰を埋め込むのに
負数の参照を使うとどのように容易になるかを示します:
my $parens = qr/(\((?:[^()]++|(?-1))*+\))/; if (/foo $parens \s+ + \s+ bar $parens/x) { # do something here... }
補足 このパターンは PCRE や Python での等価な形式の構成子と同じように 振る舞うわけではありません。 Perl においては再帰グループの中にバックトラックできますが、PCRE や Python ではグループへの再帰はアトミックに扱われます。 また、修飾子はコンパイル時に解決されるので、(?i:(?1)) や (?:(?i)(?1)) といった構成子はサブパターンがどのように処理されたかに 影響されません。
(?&NAME)
名前付きサブパターンへの再帰。
再帰するかっこが名前によって決定される点以外は (?PARNO)
と等価です。
もし複数のかっこで同じ名前を持っていた場合には一番左のものに再帰します。
パターンのどこでも宣言されていない名前の参照はエラーになります。
補足: Python または PCRE 正規表現エンジンに慣れているプログラマが
簡単になるように (?&NAME)
の代わりに (?P>NANE)
を使うことも
できます。
(?(condition)yes-pattern|no-pattern)
(?(condition)yes-pattern)
条件付き式。
(condition)
はかっこでくるまれた数値(対応するかっこ対が
マッチングしたときに有効)、先読み/後読み/ゼロ幅で評価される言明、角かっこ
もしくはシングルクォートでくるまれた名前(その名前のバッファが
マッチングしたときに有効)、特殊なシンボル (R) (再帰または eval 内で
評価されているときに真)のいずれかです。
加えて R には数字(対応するグループ内で再帰しているときに真)、もしくは
&NAME
、こちらの時はその名前のグループで再帰している時にのみ真、を
続けることもできます。
可能な述語の要約を次に示します:
その番号の捕捉バッファが何かにマッチングしたかどうかを調べます。
その名前のバッファが何かにマッチングしたかどうかを調べます。
コードブロックを条件として扱います。
式が再帰の中で評価されているかどうかを調べます。
式がその n 番目の捕捉グループのすぐ内側で実行されているかどうかを調べます。 これは次のものと等価な正規表現です
if ((caller(0))[3] eq 'subname') { ... }
言い換えると、これは完全な再帰スタックを調べるわけではありません。
(R1)
と似ていて、この述語はその名前のつけられている一番左のグループの
すぐ内側で実行されているかどうかをしらべます(一番左は (?NAME)
と
同じロジックです)。
これは完全なスタックを調べずに、一番内部のアクティブな再帰の名前だけを
調べます。
この場合において、yes-pattern は直接は実行されず、no-pattern は
許可されていません。
(?{0})
と似ていますがより効率的です。
詳細は次のようになります。
例:
m{ ( \( )? [^()]+ (?(1) \) ) }x
これはかっこ以外からなる固まりかかっこの中にあるそれらにマッチングします。
(DEFINE)
は特殊な形式で、これはその yes-pattern を直接は実行せず、
no-pattern も許可していません。
これは再帰メカニズムの中で利用することでのみ実行されるサブパターンの
定義を許可します。
これによって、選んだパターンと一緒に正規表現ルールを定義できます。
この使い方において、DEFINE ブロックはパターンの最後におくこと、 そしてそこで定義する全てのサブパターンに名前をつけることが 推奨されています。
また、この方法によって定義されるパターンはその処理に関してそんなに 賢い訳ではないので効率的でないことに価値は何もないでしょう。
これをどのように使うかの例を次に示します:
/(?<NAME>(?&NAME_PAT))(?<ADDR>(?&ADDRESS_PAT)) (?(DEFINE) (?<NAME_PAT>....) (?<ADRESS_PAT>....) )/x
再帰の内側でマッチングした捕捉バッファは再帰から戻った後には
アクセスできないため、余分な捕捉バッファの
レイヤは必要な点に注意してください。
従って $+{NAME}
が定義されていても $+{NAME_PAT}
は定義されません。
(?>pattern)
「独立した」部分式、スタンドアロンの pattern
がその場所に
固定されてマッチングする部分文字列にマッチングし、
その文字列以外にはなにもマッチングしません。
この構成子は他の"外部"マッチングになる最適化に便利です;
なぜならこれはバックトラックしないためです(バックトラック 参照)。
これは "できる限りを取り込んで、後は戻らない"セマンティクスが
必要な場所でも便利です。
例: ^(?>a*)ab
は何もマッチングしません、
なぜなら (?>a*)
(前述のように、文字列の開始で固定されます)は
文字列のはじめにある全ての文字 a
にマッチングし、
ab
のマッチングのための a
を残さないためです。
対照的に、a*ab
は a+b
と同じようにマッチングします、
これはサブグループ a*
のマッチングは次のグループ ab
の影響を
受けるためです (バックトラック 参照)。
特に、a*ab
の中の a*
は単独の a*
より短い文字にマッチングします;
これによって最後のマッチングが行えるようになります。
(?>pattern)
と似た効果は (?=(pattern))\1
でも達成できます。
これは単独の a+
と同じ部分文字列にマッチングし、それに続く \1
が
マッチングした文字列を消費します;
これはゼロ幅の言明が (?>...)
の類似を作るためです。
(この2つの構成子は後者はグループをキャプチャするため、
それに続く正規表現の残りで後方参照の順序をずらす点で違いがあります)。
次のパターンを考えてみてください:
m{ \( ( [^()]+ # x+ | \( [^()]* \) )+ \) }x
これは 2 段階までのかっこでくるまれた空でないグループに効率的に
マッチングします。
しかしながら、これはマッチングするグループがなかったときに長い
文字列においてはほとんど永遠に戻りません。
これは長い文字列をいくつかの部分文字列に分解する方法がいくつもあるためです。
これは (.+)+
が行うことでもあり、(.+)+
は このパターンの
部分パターンと似ています。
このパターンが ((()aaaaaaaaaaaaaaaaaa
にはマッチングしないことを
どうやって検出するかを少し考えてみましょう、
しかしここでは余計な文字を2倍にしてみます。
この指数的なパフォーマンスはプログラムのハングアップとして表面化します。
しかしながら、このパターンに小さな変更をいれてみます,
m{ \( ( (?> [^()]+ ) # change x+ above to (?> x+ ) | \( [^()]* \) )+ \) }x
これは上で行っているように (?>...)
マッチングを
使っています(これは自身で確認してみるとよいでしょう)が、
しかし 1000000 個の a
からなる似た文字列を使ってみると、4 分の 1 の
時間で完了します。
しかしながら、このパターンは現在のところ use warnings
プラグマまたは
-w スイッチの影響下では "matches null string many times in regex"
(正規表現において空文字列に何回もマッチングしました) という警告を
発するでしょう。
パターン (?> [^()]+ )
のような簡単なグループでは、
比較できる影響は [^()]+ (?! [^()] )
のように負の先読みの
言明で達することができます。
これは 1000000 個の a
からなる文字列において 4 倍だけ遅くなります。
最初の ()*
のような正しい解法となる多くの状況において
「できる限りを取り込んで、後は戻らない」セマンティクスが望まれるものです。
任意で(水平)空白の続く #
によって区切られるコメントのついたテキストの
パースを考えてみます。
その出現と対比して、#[ \t]*
はコメント区切りにマッチングする
正しい部分式ではありません; なぜならパターンの残りがそれのマッチングを
作ることができるのならそれはいくつかの空白を「あきらめてしまう」ためです。
正しい回答は以下のいずれかです:
(?>#[ \t]*) #[ \t]*(?![ \t])
例えば空でないコメントを $1 に取り込むためには次のいずれかを使います:
/ (?> \# [ \t]* ) ( .+ ) /x; / \# [ \t]* ( [^ \t] .* ) /x;
選んだ方はコメントの仕様をより適切に反映した式に依存します。
いくつかの書籍においてこの構成子は「アトミックなマッチング」 または「絶対最大量マッチング(possessive matching)」と呼ばれます。
絶対最大量指定子はそれが適用されている項目をこれらの構成子の中に置くことと 等価です。 以下の等式が適用されます:
Quantifier Form Bracketing Form --------------- --------------- PAT*+ (?>PAT*) PAT++ (?>PAT+) PAT?+ (?>PAT?) PAT{min,max}+ (?>PAT{min,max})
警告: これらのパターンは実験的なものであり、 Perl の今後のバージョンで変更または削除される可能性があります。 製品コードでこれらを使う際にはアップグレードによる問題を 避けるために明記するべきです。
これらの特殊なパターンは (*VERB:ARG)
という一般形式を持っています。
ARG が任意であると規定されていいないいくつかのケース以外では、それは
拒否されます。
引数を許可する特殊バックトラック制御記号を含んでいる全てのパターンは、
それが実行されると現在のパッケージの $REGERROR
及び $REGMARK
変数を
設定する特殊な振る舞いを持っています。
これが行われる時以下の手順が適用されます。
失敗時には $REGERROR
変数には、記号がマッチングの失敗の中で
使われていたのならその記号パターンの ARG の値がセットされます。
もしパターンの ARG 部分が省略されていたときには、$REGERROR
には
最後に実行された (*MARK:NAME)
パターンの名前、またはそれもなければ
真に設定されます。
また、$REGMARK
変数は偽に設定されます。
マッチングの成功時には、$REGERROR
変数は偽に設定され、$REGMARK
変数には
最後に実行された (*MARK:NAME)
パターンの名前が設定されます。
詳細は (*MARK:NAME)
記号の説明を参照してください。
補足: $REGERROR
及び $REGMARK
は $1
や他の多くの
正規表現関連の変数のようにマジック変数ではありません。
それらはスコープ内にローカルにならず、読み込み専用でもありませんが、
$AUTOLOAD
と似た揮発するパッケージ変数です。
必要時に特定のスコープ内に変更を留めたいときには local
を使ってください。
もしパターンが引数を許可する特殊バックトラック記号を含んでなかった場合には、
$REGERROR
及び $REGMARK
は全く触られません。
(*PRUNE)
(*PRUNE:NAME)
このゼロ幅のパターンは失敗でバックトラックしてきたときに現在の位置で
バックトラックツリーを刈り取ります。
A (*PRUNE) B
というパターンで A も B も複雑なパターンである時を
考えてみます。
(*PRUNE)
に達するまでは、A はマッチングに必要であれば
バックトラックしていきます。
しかし一旦そこに達して B に続くと、そこでも必要に応じてバックトラックします;
しかしながら、B がマッチングしなかったときにはそれ以上のバックトラックは
行われず、現在の開始位置でのマッチングはすぐに失敗します。
次の例ではパターンに対してマッチングできるすべての文字列を(実際には マッチングさせずに)数えます。
'aaab' =~ /a+b?(?{print "$&\n"; $count++})(*FAIL)/; print "Count=$count\n";
この出力:
aaab aaa aa a aab aa a ab a Count=9
次のように数える前に (*PRUNE)
を加えると
'aaab' =~ /a+b?(*PRUNE)(?{print "$&\n"; $count++})(*FAIL)/; print "Count=$count\n";
バックトラックを妨げ次のように各開始位置での一番長いマッチングを 数えるようになります:
aaab aab ab Count=3
1つのパターン内で (*PRUNE)
言明はいくつでも使えます。
バックトラックを制御する他の方法として (?>pattern)
及び絶対最大量指定子も参照してください。
幾つかのケースにおいては (*PRUNE)
の利用は機能的な違いなしに
(?>pattern)
で置き換えることができます; しかしながら (*PRUNE)
は
(?>pattern)
単独では表現できないケースを扱うために使えます。
(*SKIP)
(*SKIP:NAME)
このゼロ幅のパターンは *PRUNE
と似ていますが、実行されている
(*SKIP)
パターンまでにマッチングしたテキストはこのパターンの
どのマッチングの一部にもならないことを示します。
これは正規表現エンジンがこの位置まで失敗として「スキップ」して(マッチングに
十分な空間があれば)再びマッチングを試みることを効率的に意味します。
(*SKIP:NAME)
パターンの名前部分には特別な意味があります。
もしマッチングにおいて (*MARK:NAME)
に遭遇すると、それは「スキップ
位置」として使われる位置になります。
その名前の (*MARK)
と東宮していなければ、(*SKIP)
操作は効果を
持ちません。
名前がなければ「スキップ位置」は(*SKIP)パターンの実行されたときに
マッチングポイントが使われます。
以下の例を (*PRUNE)
と比べてみてください;
文字列が2倍になってることに注意してください:
'aaabaaab' =~ /a+b?(*SKIP)(?{print "$&\n"; $count++})(*FAIL)/; print "Count=$count\n";
これの出力は
aaab aaab Count=2
いったん文字列の最初の 'aaab' がマッチングして、(*SKIP)
が実行されると、
次の開始位置は (*SKIP)
が実行されたときのカーソルがいた位置になります。
(*MARK:NAME)
(*:NAME)
(*MARK:NAME)
(*:NAME)
このゼロ幅のマッチングはパターン内の特定の箇所がマッチングに成功したときに、
文字列の中で達した位置を記録するために使われます。
このマークには名前をつけることもできます。
後者の (*SKIP)
パターンは失敗時でバックトラックしたときにその箇所まで
スキップします。
(*MARK)
パターンはいくつでも使うことができて、NAME 部分は省略可能であり
重複することもあります。
(*SKIP)
パターンとの相互動作に加えて、(*MARK:NAME)
はパターン分岐の
「ラベル」としても使うことができます; このためマッチングの後で、プログラムは
そのマッチングにおいてパターンのどの分岐が使われたのかを知ることができます。
マッチングの成功時に、$REGMARK
変数はマッチングの中で一番最近に
実行された (*MARK:NAME)
の名前を設定します。
これは書く分岐で別々の捕捉バッファを使うことなしにパターンのどの分岐が
マッチングしたのかを知るために使うことができます; これは perl は
/(?:(x)|(y)|(z))/
を /(?:x(*MARK:x)|y(*MARK:y)|z(*MARK:z))/
程度に
効率的には最適化できないためパフォーマンスの向上をもたらします。
マッチングが失敗して、そして他の記号がマッチングの失敗で行われずかつ名前を
持っているというのでなければ、$REGERROR
変数には一番最近に実行された
名前が設定されます。
詳細は (*SKIP)
を参照してください。
(*MARK:NAME)
の短縮形として (*:NAME)
とも記述できます。
(*THEN)
(*THEN:NAME)
これは Perl 6 の "cut group" 演算子 ::
と似ています。
(*PRUNE)
のように、この記号は常にマッチングし、そして失敗で
バックトラックした時に正規表現エンジンに一番内側で閉じているグループ
(キャプチャでもそうでなくとも)で次の代替を試みるようにさせます。
この名前は代替演算子(|
) と連結されたこの演算子で本質的にパターンベースの
if/then/else ブロックとなるものを作るために使うことが
できることからきています:
( COND (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ )
この演算子が使われていてそしてそれが代替の内側ではなければ
これはちょうど (*PRUNE)
演算子のように動作します。
/ A (*PRUNE) B /
は次と同じです
/ A (*THEN) B /
しかし
/ ( A (*THEN) B | C (*THEN) D ) /
は次と同じではありません
/ ( A (*PRUNE) B | C (*PRUNE) D ) /
A にマッチングしたけれど B に失敗した後 (*THEN)
記号はバックトラックして
C を試みます; しかし (*PRUNE)
記号であれば単純に失敗します。
(*COMMIT)
これは Perl 6 の"コミットパターン" <commit>
または :::
です。
これは (*SKIP)
と似たゼロ幅のパターンですが、失敗でバックトラックした
際にマッチングがすぐに失敗する点で異なります。
それ以降で開始位置を進めて有効なマッチングを探す試行は行われません。
例えば、
'aaabaaab' =~ /a+b?(*COMMIT)(?{print "$&\n"; $count++})(*FAIL)/; print "Count=$count\n";
は次を出力します
aaab Count=1
言い換えると、いったん (*COMMIT)
に入った後に、そのパターンが
マッチングしなかったのなら、正規表現エンジンは文字列の残りに対して
それ以上のマッチングを試みません。
(*FAIL)
(*F)
このパターンは何にもマッチングせず常に失敗します。
これはエンジンを強制的にバックトラックさせるために使えます。
これは (?!)
と等価ですが、より読みやすくなっています。
実際、(?!)
は内部的には (*FAIL)
に最適化されます。
これはおそらく (?{})
または (??{})
と組み合わせた時にだけ
役に立つでしょう。
(*ACCEPT)
警告: この機能は強く実験的です。 製品コードでは推奨されません。
このパターンマッチングは何もせず (*ACCEPT)
パターンと遭遇した場所で
文字列の中で実際にもっとマッチングするものがあるかどうかにかかわらず
成功のマッチングを終了させます。
再帰、または (??{})
といったネストしたパターンの内側では、一番内側の
パターンのみがすぐに終了します。
(*ACCEPT)
が捕捉バッファの内側で使われた場合捕捉バッファは
(*ACCEPT)
と遭遇した位置で終了とマークされます。
例えば:
'AB' =~ /(A (A|B(*ACCEPT)|C) D)(E)/x;
はマッチングし、$1
は AB
になり、$2
は B
に、そして
$3
は設定されません。
'ACDE' のようにかっこの内側で他の分岐がマッチングしたのなら、D
及び
E
もマッチングします。
補足: このセクションでは正規表現の振る舞いに関する抽象的な概要を 説明します。 可能な代替におけるマッチングの選択におけるルールの厳密な(そして複雑な) 説明は RE の欠片の結合 を参照してください。
正規表現マッチングの基本的な機能には最近(必要であれば)すべての強欲でない
正規表現量指定子、つまり、*
, *?
, +
, +?
, {n,m}
, {n,m}?
で
使われる バックトラッキング と呼ばれる概念が含まれています。
正規表現がマッチング知る時、その正規表現の一部ではなく、 全体 がマッチングしなければなりません。 そのためもしパターンの前半にパターンの後半部分を失敗させてしまう 量指定子が含まれているのなら、マッチングングエンジンはいったん戻って 開始位置を再計算します -- これがバックトラッキングと呼ばれる所以です。
バックトラッキングの例をあげてみます: "Foo is on the foo table." という 文字列の中で "foo" に続く単語を取り出してください:
$_ = "Food is on the foo table."; if ( /\b(foo)\s+(\w+)/i ) { print "$2 follows $1.\n"; }
マッチングが実行される時、正規表現の最初の部分 (\b(foo)
) は開始文字列の
右側で可能なマッチングを探します; そして $1 に "Foo" をロードします。
しかし、すぐにマッチングエンジンは $1 に保存した "Foo" の後に空白が
無いことを見つけ、それが失敗だったことを検出して仮にマッチングさせた
場所の1文字後から開始します。
この時次の "foo" の出現まで進みます。
この時に正規表現は完全にマッチングし、予測した出力 "table follows foo." を
得ます。
最小マッチングが役立つこともあります。 "foo" と "bar" の間の全てにマッチングしたいと考えてください。 最初に、次のように書くかもしれません:
$_ = "The food is under the bar in the barn."; if ( /foo(.*)bar/ ) { print "got <$1>\n"; }
しかしこれは考えたのと違う結果となるでしょう:
got <d is under the bar in the >
これは .*
が貪欲であり、そのために 最初の "foo" と 最後の
"bar" の間にある全てを取り出してしまいます。
次に "foo" とその後の最初の "bar" の間にあるテキストを取り出す
最小マッチングを使ったもっと効率的な方法を示します:
if ( /foo(.*?)bar/ ) { print "got <$1>\n" } got <d is under the >
別の例も出してみます。 文字列の最後にある数字にマッチングさせて、そのマッチングの前の部分も 保持させてみましょう。 そしてあなたは次のように書くかもしれません。
$_ = "I have 2 numbers: 53147"; if ( /(.*)(\d*)/ ) { # Wrong! print "Beginning is <$1>, number is <$2>.\n"; }
これは全く動作しません、なぜなら .*
は貪欲であり文字列全体を
飲み込んでしまいます。
\d*
は空の文字列にマッチングできるので正規表現は完全に正常に
マッチングします。
Beginning is <I have 2 numbers: 53147>, number is <>.
動作しない主なバリエーションをあげておきます:
$_ = "I have 2 numbers: 53147"; @pats = qw{ (.*)(\d*) (.*)(\d+) (.*?)(\d*) (.*?)(\d+) (.*)(\d+)$ (.*?)(\d+)$ (.*)\b(\d+)$ (.*\D)(\d+)$ };
for $pat (@pats) { printf "%-12s ", $pat; if ( /$pat/ ) { print "<$1> <$2>\n"; } else { print "FAIL\n"; } }
これらの結果は次のようになります:
(.*)(\d*) <I have 2 numbers: 53147> <> (.*)(\d+) <I have 2 numbers: 5314> <7> (.*?)(\d*) <> <> (.*?)(\d+) <I have > <2> (.*)(\d+)$ <I have 2 numbers: 5314> <7> (.*?)(\d+)$ <I have 2 numbers: > <53147> (.*)\b(\d+)$ <I have 2 numbers: > <53147> (.*\D)(\d+)$ <I have 2 numbers: > <53147>
このように、これは幾分トリッキーです。 重要なのは正規表現は成功の定義を定める主張の集合にすぎないことを 認識することです。 特定の文字列で成功となる定義には 0, 1 または複数の違ったやり方が存在します。 そしてもし成功する複数の方法が存在するのなら成功したうちのどれが目的と するものなのかを知るためにバックトラッキングを理解しておく必要があります。
前読みの言明及び否定を使っている時にはこれはますますトリッキーになります。 "123" が後ろに続かない数字以外の列を探したいと考えてみてください。 あなたは次のように書くかもしれません。
$_ = "ABC123"; if ( /^\D*(?!123)/ ) { # Wrong! print "Yup, no 123 in $_\n"; }
ですがこれはマッチングしません; 少なくともなってほしかったようには。 これは文字列の中に 123 がないことを要求します。 よくある予想と比較してなぜパターンがマッチングするのかのわかりやすい 説明を次に示します:
$x = 'ABC123'; $y = 'ABC445';
print "1: got $1\n" if $x =~ /^(ABC)(?!123)/; print "2: got $1\n" if $y =~ /^(ABC)(?!123)/;
print "3: got $1\n" if $x =~ /^(\D*)(?!123)/; print "4: got $1\n" if $y =~ /^(\D*)(?!123)/;
これは次の出力となります
2: got ABC 3: got AB 4: got ABC
テスト 3 はテスト 1 のより一般的なバージョンなのでそれが失敗すると
考えたかもしれません。
この 2 つの重要な違いは、テスト 3 には量指定子(\D*
)が含まれているので
テスト1ではできなかったバックトラッキングを行うことが
できるところにあります。
ここであなたは「$x のはじめで 0 個以上の非数字があるから 123 ではない
何かを得られるんじゃないの?」と聞くでしょう。
このパターンマッチングが \D*
を "ABC" に展開させると
これはパターン全体を失敗させることになります。
探索エンジンは最初に \D*
を "ABC" にマッチングさせます。
そして (?!123)
を "123" にマッチングさせ、これは失敗します。
けれども量指定子 (\D*
) が正規表現の中で使われているので、探索エンジンは
バックトラックしてこの正規表現全体をマッチングさせるように異なるマッチングを
行うことができます。
このパターンは本当に、本当に 成功したいので、これは標準的なパターンの
後退再試行を行い、この時に \D*
を "AB" のみに展開させます。
そして確かに "AB" の後ろは "123" ではありません。
"C123" は十分満たしています。
これは言明と否定の両方を使うことで処理することができます。 $1 の最初の部分は数字が続きかつそれは "123" ではないことを宣言します。 先読みはゼロ幅の式なのでそれがマッチングした文字列を全く消費しないことを 思い出してください。 そしてこれを必要なものを生成するように書き換えます; つまり、5 のケースでは失敗し、6 のケースは成功します:
print "5: got $1\n" if $x =~ /^(\D*)(?=\d)(?!123)/; print "6: got $1\n" if $y =~ /^(\D*)(?=\d)(?!123)/;
6: got ABC
言い換えると、このそれぞれの次にある2つのゼロ幅の言明はちょうど何か組み込みの
言明を使ったかのようにそれらがともに AND されているかのように動作します:
/^$/
は行の始まりで且つ同時に行の終了でる時にのみマッチングします。
もっと深部での真実は、併記された正規表現は垂直線を使って明示的に OR を
書いたとき以外は常に AND を意味します。
/ab/
は、"a" がゼロ幅の言明ではなく 1 文字幅の言明なので異なる場所で
マッチングが行われはしますが、 "a" にマッチング且つ(そして) "b" に
マッチングということを意味します。
警告: 特にコンパイルされた正規表現はマッチングのために できる限りのバックトラックを非常に多くの回数行うので 解くために指数的な時間を必要とすることがあります。 例えば、正規表現エンジンの内部で行われる最適化がなかったときには、次の評価は 尋常じゃないくらい長時間かかります:
'aaaaaaaaaaaa' =~ /((a{0,5}){0,5})*[c]/
そしてもし内側のグループで 0 から 5 回にマッチングを制限する代わりに
*
を使うと、永久に、またはスタックを使い果たすまで
実行し続けることになります。
その上、これらの最適化は常にできるわけではありません。
例えば、外側のグループで *
の代わりに {0,5}
を使ったときに、現在の
最適化は適用されません; そしてマッチングが終わるまでの長い時間が
必要になります。
そのような野獣のような最適化のためのパワフルなツールとして
知られているものに、「独立グループ」があります; これはバックトラックを
行いません (< (?>pattern) >
を参照)。
ゼロ幅の先読み/後読みの言明も「論理的な」文脈なので末尾のマッチングを
バックトラックしません: マッチングが関連して考慮されるかどうかだけです。
先読みの言明の副作用がそれに続くマッチングに影響する かもしれない 例は、
< (?>pattern) >
を参照してください。
「通常の」バージョン 8 正規表現ルーチンに詳しくないのであれば、ここには これまでに説明されていないパターンマッチングルールがあります。
すべての単一の文字は、それが個々でまたはこれまでに説明した特別な意味を 持っている メタ文字 である場合以外は、文字それ自身にマッチングします。 文字は "\" で前置されることで通常はメタ文字としての機能を持っている文字を リテラルとして処理させれるようになります(つまり、"\." は任意の 1 文字ではなく "." にマッチングするようになり、"\\" は "\" にマッチングするようになります。 このエスケープ機構はパターン区切りとして使われている文字でも必要です。
一連の文字は対象とする文字列の中で同じ一連の文字列にマッチングします;
なので blurfl
というパターンは対象とする文字列の中の "blurfl" に
マッチングします。
[]
で文字のリストを囲むことで文字クラスを指定することができます;
これはリストの中の任意の文字にマッチングします。
もし "[" の後の最初の文字が "^" だったときには、その文字クラスは
リストの中にない任意の文字にマッチングします。
リストの中では、文字 "-" は範囲を意味します; なので a-z
は "a" と "z" を
含めてそれらの間にあるすべての文字を表現します;
文字クラスの要素として "-" または "]" を使いたい時には、リストの先頭に
(あるいは"^"の後に)置くか、バックスラッシュを使ってエスケープします。
"-" はリストの終端、リストを閉じる "]" の直前にあったときもリテラルとして
扱われます。
(次の例はすべて同じ3文字からなる文字クラスです: [-az]
, [az-]
,
[a\-z]
。
これらはすべて EBCDIC ベースの文字集合であっても26文字からなる文字集合
[a-z]
とは異なります。) また、範囲の端点として文字クラス \w
, \W
,
\s
, \S
, \d
, \D
を使ったときも "-" はリテラルとして
処理されます。
範囲全体というアイデアは文字集合間でポータブルではありません -- そして 結果となる文字集合では予期したものではないでしょう。 ひとつの安全策としては同じケースの英字の([a-e], [A-E]), または数字([0-9])という範囲でのみ使うことです。 これ以外は安全ではありません。 もし信じられないのであれば文字集合を完全につづってみてください。
文字は C でよく使われているようなメタ文字の構文を使って指定することも
できます: "\n" は改行にマッチングし、"\t" はタブに、"\r" は復帰に、
"\f" はフォームフィードにといった具合にマッチングします。
より一般的に、\nnn (nnn は8進数字) はその文字集合でコード値
nnn の文字にマッチングします。
同じように、\xnn (nn は16進数字) は数値で nn になる文字に
マッチングします。
式 \cx は制御文字 x にマッチングします。
そして最後に、"." メタ文字は (/s
を使っていない限り) "\n" 以外の任意の
文字にマッチングします。
"|" を使ってパターンを区切って一連の代替を指定することもできます; なので
fee|fie|foe
は対象の文字列の "fee"、"fie"、または "foe" のいずれかに
(f(e|i|o)e
のように)マッチングします。
最初の代替には最後のパターン区切り ("(", "[", またはパターンの始まり)から
最初の "|" までのすべてが含まれ、最後の代替には最後の "|" から
次のパターン区切りまでが含まれます。
通常代替をかっこの中に入れるのは、その開始位置と終了位置が少しはわかりやすく
なるようにです。
代替は左から右へと試されます、なので最初の代替がその完全な式で
マッチングしたのならそれが選択されます。
これは代替は貪欲である必要はないということを意味します。
例えば: "barefoot" に対して foo|foot
をマッチングさせると、最初の代替から
試されるので、"foo" の部分がマッチングし、これは対象の文字列に対して成功で
マッチングします。
(これは重要ではないでしょうが、かっこを使ってマッチングしたテキストを
捕捉しているときには重要でしょう)。
また "|" は角かっこの中ではリテラルとして処理されるので、
[fee|fie|foe]
と書くとこれは実際には [feio|]
にのみマッチングします。
パターンにおいて、後で参照するためにかっこで括って部分パターンを指定できます;
してメタ文字 \n を使ってパターンの後の方で n 番目の部分パターンを
参照することができます。
部分パターンはその開きかっこの左から右への順に番号づけられます。
後方参照は評価された文字列の中でその部分パターンに実際にマッチングしたものに
マッチングします。
従って、(0|0x)\d*\s\1\d*
は "0x1234 0x4321" にはマッチングしますが、
"0x1234 01234" にはマッチングしません; なぜなら、0|0x
は二つめ数字の
先頭にある 0 にマッチングすることができるのですが、
部分パターン 1 は "0x" にマッチングするためです。
次のように書くことになれている人も中にはいるでしょう:
$pattern =~ s/(\W)/\\\1/g;
sed 中毒な人をびっくりさせないための RHS 置換の祖先ですが、しかしこれは
汚らしい癖です。
Perl においては、s///
の右側はダブルクォートされた文字列と
考えられるためです。
通常のダブルクォートされた文字列の中では \1
は control-A を意味します。
\1
の Unix での習慣的な意味は s///
だけのその場しのぎです。
しかしながら、この癖に漬かっていると /e
修飾子を使ったときに
トラブルとなるでしょう。
s/(\d+)/ \1 + 1 /eg; # causes warning under -w
または次のようにするかもしれません
s/(\d+)/\1000/;
これを解消するために \{1}000
としないでください;
ここでは ${1}000
とするべきです。
埋め込みの処理は後方参照にマッチングさせる操作より混乱は少ないでしょう。
特に s///
の 左 側では2つの異なった意味になります。
警告: この先には難しい(そして無味乾燥な)内容があります。 このセクションは書き直す必要があるでしょう。
正規表現は簡潔でパワフルなプログラミング言語を提供します。 他の多くの強力なツールとともに、力は破壊の源にもなります。
この力のよくある乱用は無害な何かとともに、正規表現使った 無限ループとなります。
'foo' =~ m{ ( o? )* }x;
o?
は 'foo'
の始まりにマッチングし、文字列中での位置はこの
マッチングでは動かないので、o?
は *
量指定子によって何回も
マッチングします。
同じような繰り返しを作るもう一つのよくある形として //g
修飾子を使った
ループがあります:
@matches = ( 'foo' =~ m{ o? }xg );
または
print "match: <$&>\n" while 'foo' =~ m{ o? }xg;
または split()
による暗黙のループ。
しかしながら、長きにわたる経験からいくつかのプログラミングタスクは ゼロ幅の部分文字列に対するマッチングを行う部分式の繰り返しで大幅に 単純にできることがわかりました。 簡単な例を挙げてみます:
@chars = split //, $string; # // is not magic in split ($whitewashed = $string) =~ s/()/ /g; # parens avoid magic s// /
このように Perl は 強制的に無限ループを砕く ことによってこういった構築を
可能にしています。
このためのルールは貪欲な量指定子 *+{}
によって与えられる
低レベルなループとも、/g
修飾子や split()
演算子による
高レベルなループとも異なります。
低レベルなループは Perl がゼロ幅の部分文字列に対してマッチングする式が 繰り返されたことを検出すると 中断 されます (つまり、ループは壊されます)。 従って
m{ (?: NON_ZERO_LENGTH | ZERO_LENGTH )* }x;
は次と等価にされます
m{ (?: NON_ZERO_LENGTH )* | (?: ZERO_LENGTH )? }x;
高レベルのループは各繰り返しの間に最後のマッチングがゼロ幅だったかどうかを 追加で保持しています。 ループを終えるために、ゼロ幅のマッチングの後のマッチングはゼロ幅と なることを拒否します。 この禁則処理はバックトラックと相互に動作し(バックトラック 参照)、そして ベストな マッチングがゼロ幅だったのなら 2 番目にベストな マッチングが選択されます。
例:
$_ = 'bar'; s/\w??/<$&>/g;
これは <><b><><a><><r><>
となります。
文字列の各位置に於いて、貪欲でない ??
によって得られるベストな
マッチングはゼロ幅のマッチングです、
そして 2 番目にベストなマッチングは \w
によってマッチングするものです。
従ってゼロ幅のマッチングは 1 文字幅のマッチングの代替となります。
同じように、m/()/g
の繰り返しでは文字列中の境界一つ遠い位置に 2 番目に
ベストなマッチングがマッチングします。
ゼロ幅にマッチングしている という追加の状態はマッチングした文字列に
関連づけられていて、pos() に対する割り当てによってリセットされます。
前のマッチングの終端でのゼロ幅のマッチングは split
の間は無視されます。
これまでに説明された (ab
や \Z
といった) 正規表現の基本的な欠片
それぞれは、入力文字列上の与えられた位置で多くとも1つの部分文字列に
マッチングします。
しかしながら、典型的な正規表現ではこれらの基本的な欠片は結合演算
ST
、S|T
、S*
等(ここで S
や T
は正規表現の部分式)を使って
より複雑なパターンへと合成することができます。
このような合成には選択の問題を導くために代替を含めることができます:
正規表現 a|ab
を "abc"
に対してマッチングさせようとしたとき、これは
"a"
と "ab"
のどちらにマッチングするのか?
実際にどちらがマッチングするのかを説明する1つの方法として、
バックトラッキングのコンセプトがあります(バックトラック 参照)。
しかしながら、この説明は低レベルすぎて特定の実装を考えなければなりません。
もう一つの説明は"より良い"/"より悪い"の考え方で始めます。 与えられた正規表現にマッチングするすべての部分文字列は「最良の」 マッチングから「最悪の」マッチングへとソートすることができます; そして 「最良の」マッチングが選択されます。 これは「どれが選ばれるのか?」という問いかけを「どのマッチングがより良くて、 それがより悪いのか?」という問いかけに置き換えることができます。
そして、基本的な要素ではそういった問いかけはありません;
なぜならこれらは与えられた位置で可能なマッチングは多くとも1つだからです。
このセクションでは結合演算のより良い/より悪いの考え方で説明していきます。
以下の説明では S
及び T
は正規表現の部分式です。
ST
2つの可能なマッチング、AB
及び A'B'
を考えます;
ここで A
及び A'
は S
にマッチングする部分文字列、
そして B
及び B'
は T
にマッチングする部分文字列とします。
もし A
が S
に対して A'
よりも良いマッチングであれば、
AB
は A'B'
よりも良いマッチングです。
もし A
と A'
が同じであれば: B
が T
に対して B'
よりも
良いマッチングであれば AB
は AB'
よりも良いマッチングです。
S|T
S
がマッチングできる時は T
のみがマッチングするよりも良い
マッチングです。
S{REPEAT_COUNT}
SSS...S
(必要なだけ繰り返し)としてマッチングします。
S{min,max}
S{max}|S{max-1}|...|S{min+1}|S{min}
としてマッチングします。
S{min,max}?
S{min}|S{min+1}|...|S{max-1}|S{max}
としてマッチングします。
S?
, S*
, S+
それぞれ S{0,1}
, S{0,BIG_NUMBER}
, S{1,BIG_NUMBER}
と同じです。
S??
, S*?
, S+?
それぞれ S{0,1}?
, S{0,BIG_NUMBER}?
, S{1,BIG_NUMBER}?
と同じです。
(?>S)
S
の最良のみマッチングします。
(?=S)
, (?<=S)
S
の最良のマッチングのみが考慮されます。
(これは S
がキャプチャかっこを持っていて、そして正規表現全体の
どこかで後方参照が使われている時のみ重要です.)
(?!S)
, (?<!S)
このグループ演算子では、S
がマッチングできるかどうかのみが重要なので、
順序についての説明は必要ありません。
(??{ EXPR })
, (?PARNO)
順序は EXPR の結果の正規表現、または捕捉バッファ PARNO に含まれている パターンと同じです。
(?(condition)yes-pattern|no-pattern)
既に決定している yes-pattern
または no-pattern
を実際に
マッチングさせます。
マッチングの順序は選択された部分式と同じです。
ここにあげたレシピは与えられた位置でのマッチングの順序について 説明しています。 正規表現全体でマッチングがどのように決定されるかを理解するためには もう少しルールが必要です: より若い位置でのマッチングは後ろの方でのマッチングよりもより良いです。
オーバーロードされた定数(overload 参照)を使って RE エンジンの機能を 拡張する簡単な方法を提供することができます。
新しい正規表現エスケープシーケンス、空白文字と非空白文字との
境界にマッチングする \Y|
を作ってみることにします。
この位置には実際には (?=\S)(?<!\S)|(?!\S)(?<=\S)
がマッチングするので、
この複雑なバージョンを \Y|
で置き換えたいとします。
このために customre
モジュールを作ります:
package customre; use overload;
sub import { shift; die "No argument to customre::import allowed" if @_; overload::constant 'qr' => \&convert; }
sub invalid { die "/$_[0]/: invalid escape '\\$_[1]'"}
# We must also take care of not escaping the legitimate \\Y| # sequence, hence the presence of '\\' in the conversion rules. my %rules = ( '\\' => '\\\\', 'Y|' => qr/(?=\S)(?<!\S)|(?!\S)(?<=\S)/ ); sub convert { my $re = shift; $re =~ s{ \\ ( \\ | Y . ) } { $rules{$1} or invalid($re,$1) }sgex; return $re; }
これで use customre
することで正規表現定数の中で新しいエスケープを
使うことが出来ます; すなわち、これには何の実行時変数の埋め込みもいりません。
overload に書かれているように、この変換は正規表現のリテラル部分にのみ
動作します。
\Y|$re\Y|
であればこの正規表現の変数部分は明示的に変換する
必要があります(とはいえ $re の中でも \Y|
を有効にしたい時のみ)。
use customre; $re = <>; chomp $re; $re = customre::convert $re; /\Y|$re\Y|/;
Perl 5.10.0 時点では Perl は幾つかの Python/PCRE 的な正規表現構文拡張を サポートします。 Perl プログラマはこれらの Perl としての構文を推奨しますが、以下のものも 受理されます:
(?P<NAME>pattern)
名前付の捕捉バッファの定義。
(?<NAME>pattern)
と等価。
(?P=NAME)
名前付捕捉バッファへの後方参照。
\g{NAME}
と等価。
(?P>NAME)
名前付き捕捉バッファへの関数呼び出し。
(?&NAME)
と等価。
この文書は、理解が困難なところから、完全かつ徹底的に不明瞭なところまで さまざまです。 jargon に満ちたとりとめのない散文は幾つかの箇所で理解するのに 難儀ではあるでしょう。
この文書はリファレンス的な内容からチュートリアル的な内容を分離して 書き直す必要があります。
Regexp Quote-Like Operators in perlop.
Gory details of parsing quoted constructs in perlop.
perlebcdic.
O'Reilly and Associates から出版されている、Jeffrey Friedl による Mastering Regular Expressions (詳説 正規表現)