argra****@users*****
argra****@users*****
2008年 12月 22日 (月) 04:09:16 JST
Index: docs/perl/5.10.0/perlretut.pod diff -u docs/perl/5.10.0/perlretut.pod:1.2 docs/perl/5.10.0/perlretut.pod:1.3 --- docs/perl/5.10.0/perlretut.pod:1.2 Sat Dec 20 03:57:19 2008 +++ docs/perl/5.10.0/perlretut.pod Mon Dec 22 04:09:16 2008 @@ -101,11 +101,15 @@ =end original -本チュートリアルでは表記に関して一度に一つずつ、そして例を多く挙げて正規表現のコンセプトを論じることによって、学習曲線を平坦化します。 -本チュートリアルの最初の部分は基本的な正規表現のコンセプトのための単純な単語検索から始まります。 -最初の部分をマスターすれば、必要とすることの98%を解決するのに必要なツールを得ることになるでしょう。 +本チュートリアルでは表記に関して一度に一つずつ、そして例を多く挙げて +正規表現のコンセプトを論じることによって、学習曲線を平坦化します。 +本チュートリアルの最初の部分は基本的な正規表現のコンセプトのための単純な +単語検索から始まります。 +最初の部分をマスターすれば、必要とすることの 98% を解決するのに必要な +ツールを得ることになるでしょう。 本チュートリアルの二番目の部分はより強力なツールのために十分なものです。 -そこではより高度な正規表現演算子について論じ、5.6.0で導入された最新の機能を紹介します。 +そこではより高度な正規表現演算子について論じ、5.6.0 で導入された最新の +機能を紹介します。 =begin original @@ -245,8 +249,8 @@ =end original "Hello World" =~ m!World!; # マッチする。デリミタは '!' - "Hello World" =~ m{World}; # マッチする。組になっている'{}' に注意 - "/usr/bin/perl" =~ m"/perl"; # 'usr/bin'の後にマッチする + "Hello World" =~ m{World}; # マッチする。組になっている '{}' に注意 + "/usr/bin/perl" =~ m"/perl"; # 'usr/bin' の後にマッチする # '/' は普通の文字になっている =begin original @@ -268,13 +272,23 @@ =end original -異なる正規表現がどのように C<"Hello World"> にマッチするか考えてみましょう: +異なる正規表現がどのように C<"Hello World"> にマッチするか +考えてみましょう: + +=begin original "Hello World" =~ /world/; # doesn't match "Hello World" =~ /o W/; # matches "Hello World" =~ /oW/; # doesn't match "Hello World" =~ /World /; # doesn't match +=end original + + "Hello World" =~ /world/; # マッチしない + "Hello World" =~ /o W/; # マッチする + "Hello World" =~ /oW/; # マッチしない + "Hello World" =~ /World /; # マッチしない + =begin original The first regexp C<world> doesn't match because regexps are @@ -297,8 +311,8 @@ スペース ' 'は正規表現の中で他の文字と同じように扱われ、この場合 マッチするのに必要なものです。 スペースがないことが三番目の正規表現 C<'oW'> がマッチしない理由です。 -四番目の正規表現は正規表現の末尾にスペースがついているのに、文字列の末尾には -スペースがないのでマッチしません。 +四番目の正規表現は正規表現の末尾にスペースがついているのに、文字列の +末尾にはスペースがないのでマッチしません。 このレッスンでは正規表現は、文が真となるためには I<その通り> に文字列の 一部としてマッチしなければならないことを示しました。 @@ -319,8 +333,8 @@ =end original - "Hello World" =~ /o/; # 'Hello'の'o'にマッチ - "That hat is red" =~ /hat/; # 'That'の中の'hat'にマッチ + "Hello World" =~ /o/; # 'Hello' の 'o' にマッチ + "That hat is red" =~ /hat/; # 'That' の中の 'hat' にマッチ =begin original @@ -331,9 +345,12 @@ =end original -文字マッチングに対する関心と共に、知っておくべき幾つかのポイントがあります。 -まず始めに、すべての文字がマッチにおいて'あるがまま'(as is) に使われるのではないということです。 -I<メタ文字> と呼ばれる幾つかの文字が正規表現の記述に使うために予約されています。 +文字マッチングに対する関心と共に、知っておくべき幾つかのポイントが +あります。 +まず始めに、すべての文字がマッチにおいて'あるがまま'(as is) に +使われるのではないということです。 +I<メタ文字> と呼ばれる幾つかの文字が正規表現の記述に使うために +予約されています。 メタ文字には以下のものがあります {}[]()^$.|*+?\ @@ -346,9 +363,10 @@ =end original -これらの文字のそれぞれの重要性は本チュートリアルの残りの部分で説明されますが、 -今のところは、メタ文字はバックスラッシュを前置することによって -マッチさせることができることを知っておくことが重要です: +これらの文字のそれぞれの重要性は本チュートリアルの残りの部分で +説明されますが、今のところは、メタ文字はバックスラッシュを +前置することによってマッチさせることができることを知っておくことが +重要です: =begin original @@ -362,7 +380,7 @@ "2+2=4" =~ /2+2/; # マッチしない。+ はメタ文字 "2+2=4" =~ /2\+2/; # マッチする。\+ 普通の + のように扱われる - "The interval is [0,1)." =~ /[0,1)./ # これはシンタックスエラー! + "The interval is [0,1)." =~ /[0,1)./ # これは文法エラー! "The interval is [0,1)." =~ /\[0,1\)\./ # マッチする "#!/usr/bin/perl" =~ /#!\/usr\/bin\/perl/; # マッチする @@ -375,7 +393,7 @@ =end original -最後の正規表現では、スラッシュ C<'/'>もまたバックスラッシュが +最後の正規表現では、スラッシュ C<'/'> もまたバックスラッシュが つけられています。 なぜなら、それが正規表現のデリミタとして使われているからです。 これは LTS(leaning toothpick syndrome つまようじ大好き症候群?)を @@ -425,7 +443,7 @@ I<エスケープシーケンス> によって表現されるいくつかの ASCII 文字があります。 一般的な例では、タブを表す C<\t>、改行を表す C<\n>、復帰を表す C<\r>、 ベルを表す C<\a> があります。 -文字列を任意のバイト列としてみなすのなら、C<\033>のような +文字列を任意のバイト列としてみなすのなら、C<\033> のような 8 進エスケープシーケンスや C<\x1B> のような 16 進エスケープシーケンスは バイト列のより自然な表現となります。 以下にあげるのはエスケープの例です: @@ -441,9 +459,8 @@ "1000\t2000" =~ m(0\t2) # マッチする "1000\n2000" =~ /0\n20/ # マッチする - "1000\t2000" =~ /\000\t2/ # マッチしない。 -"0" は "\000" ではない - "cat" =~ /\143\x61\x74/ # matches, but a weird way to spell cat + "1000\t2000" =~ /\000\t2/ # マッチしない。"0" は "\000" ではない + "cat" =~ /\143\x61\x74/ # マッチするが、cat を綴る変な方法 =begin original @@ -457,17 +474,30 @@ =end original -あなたがすでにPerlを少なからず知っているのなら、エスケープシーケンスに付いて述べた以上のことはすでになじみ深いものかもしれません。 -同じようなエスケープシーケンスはダブルクォートで囲まれた文字列で使われていて、事実Perlにおける正規表現はほとんどの場合においてダブルクォートで囲まれた文字列のように扱われます。 +あなたがすでに Perl を少なからず知っているのなら、エスケープシーケンスに +付いて述べた以上のことはすでになじみ深いものかもしれません。 +同じようなエスケープシーケンスはダブルクォートで囲まれた文字列で +使われていて、事実 Perl における正規表現はほとんどの場合において +ダブルクォートで囲まれた文字列のように扱われます。 このことは正規表現の中で変数を使うことができるということを意味します。 -ダブルクォートで囲まれた文字列のように、正規表現中の変数の値はマッチのために正規表現が評価されるより前に置き換えが行われます。 +ダブルクォートで囲まれた文字列のように、正規表現中の変数の値は +マッチのために正規表現が評価されるより前に置き換えが行われます。 ですから: +=begin original + $foo = 'house'; 'housecat' =~ /$foo/; # matches 'cathouse' =~ /cat$foo/; # matches 'housecat' =~ /${foo}cat/; # matches +=end original + + $foo = 'house'; + 'housecat' =~ /$foo/; # マッチする + 'cathouse' =~ /cat$foo/; # マッチする + 'housecat' =~ /${foo}cat/; # マッチする + =begin original So far, so good. With the knowledge above you can already perform @@ -515,7 +545,8 @@ =end original このプログラムを理解するのは簡単です。 -C<#!/usr/bin/perl> はシェルから perl プログラムを起動する標準的な方法です。 +C<#!/usr/bin/perl> はシェルから perl プログラムを起動する標準的な +方法です。 S<C<$regexp = shift;>> は最初のコマンドライン引数を正規表現として 使うために保存します。 そして残りのコマンドライン引数はファイルとして扱うために @@ -524,7 +555,8 @@ 実行されます。 各行において、S<C<print if /$regexp/;>> はその行が正規表現に マッチしていれば行の内容を出力します。 -この行で、C<print> と C</$regexp/> は暗黙にデフォルト変数 C<$_> を使用します。 +この行で、C<print> と C</$regexp/> は暗黙にデフォルト変数 C<$_> を +使用します。 =begin original @@ -538,18 +570,30 @@ =end original -これまでの正規表現では、文字列のどこかでマッチすればマッチしたとみなしてきました。 -しかし、ときには文字列の I<どこで> 正規表現がマッチするのかを指定したいときがあります。 +これまでの正規表現では、文字列のどこかでマッチすればマッチしたと +みなしてきました。 +しかし、ときには文字列の I<どこで> 正規表現がマッチするのかを +指定したいときがあります。 これを行うためには、I<アンカー> メタ文字である C<^> と C<$> を使います。 アンカー C<^> は文字列の先頭でマッチすることを意味し、アンカー C<$> は -文字列の末尾(あるいは文字列の末尾にある改行の前) でマッチすることを意味します。 +文字列の末尾(あるいは文字列の末尾にある改行の前) でマッチすることを +意味します。 以下に例を挙げます: +=begin original + "housekeeper" =~ /keeper/; # matches "housekeeper" =~ /^keeper/; # doesn't match "housekeeper" =~ /keeper$/; # matches "housekeeper\n" =~ /keeper$/; # matches +=end original + + "housekeeper" =~ /keeper/; # マッチする + "housekeeper" =~ /^keeper/; # マッチしない + "housekeeper" =~ /keeper$/; # マッチする + "housekeeper\n" =~ /keeper$/; # マッチする + =begin original The second regexp doesn't match because C<^> constrains C<keeper> to @@ -578,10 +622,18 @@ つまり、その正規表現は文字列全体にマッチするのです。 以下の例で考えてみましょう +=begin original + "keeper" =~ /^keep$/; # doesn't match "keeper" =~ /^keeper$/; # matches "" =~ /^$/; # ^$ matches an empty string +=end original + + "keeper" =~ /^keep$/; # マッチしない + "keeper" =~ /^keeper$/; # マッチする + "" =~ /^$/; # ^$ は空文字列にマッチする + =begin original The first regexp doesn't match because the string has more to it than @@ -685,11 +737,20 @@ 集合はその内側に置かれます。 以下はその例です: +=begin original + /cat/; # matches 'cat' /[bcr]at/; # matches 'bat, 'cat', or 'rat' /item[0123456789]/; # matches 'item0' or ... or 'item9' "abc" =~ /[cab]/; # matches 'a' +=end original + + /cat/; # 'cat' にマッチ + /[bcr]at/; # 'bat, 'cat', 'rat' にマッチ + /item[0123456789]/; # 'item0' または ... または 'item9' にマッチ + "abc" =~ /[cab]/; # 'a' にマッチ + =begin original In the last statement, even though C<'c'> is the first character in @@ -703,9 +764,16 @@ なぜなら、文字列の最初の文字位置が正規表現がマッチすることのできる 最初の位置にある文字だからです。 +=begin original + /[yY][eE][sS]/; # match 'yes' in a case-insensitive way # 'yes', 'Yes', 'YES', etc. +=end original + + /[yY][eE][sS]/; # 大小文字を問わず 'yes' にマッチする + # 'yes', 'Yes', 'YES' など + =begin original This regexp displays a common task: perform a case-insensitive @@ -756,12 +824,22 @@ 以下は特殊文字 C<]$\> を扱うやり方です: (TBT) +=begin original + /[\]c]def/; # matches ']def' or 'cdef' $x = 'bcr'; /[$x]at/; # matches 'bat', 'cat', or 'rat' /[\$x]at/; # matches '$at' or 'xat' /[\\$x]at/; # matches '\at', 'bat, 'cat', or 'rat' +=end original + + /[\]c]def/; # ']def' または 'cdef' にマッチ + $x = 'bcr'; + /[$x]at/; # 'bat', 'cat', 'rat' にマッチ + /[\$x]at/; # '$at' または 'xat' にマッチ + /[\\$x]at/; # '\at', 'bat, 'cat', 'rat' にマッチ + =begin original The last two are a little tricky. In C<[\$x]>, the backslash protects @@ -827,11 +905,20 @@ そうでないばあいにはマッチは失敗します。 ですから +=begin original + /[^a]at/; # doesn't match 'aat' or 'at', but matches # all other 'bat', 'cat, '0at', '%at', etc. /[^0-9]/; # matches a non-numeric character /[a^]at/; # matches 'aat' or '^at'; here '^' is ordinary +=end original + + /[^a]at/; # 'aat' や 'at' にはマッチしないが、その他の + # 'bat', 'cat, '0at', '%at' などにはマッチする + /[^0-9]/; # 数字以外にマッチする + /[a^]at/; # 'aat' か '^at'にマッチする。ここでは '^' は通常の文字 + =begin original Now, even C<[0-9]> can be a bother to write multiple times, so in the @@ -949,6 +1036,8 @@ C<\d\s\w\D\S\W> の省略記法は文字クラスの内側でも外側でも使うことができます。 以下はその例です: +=begin original + /\d\d:\d\d:\d\d/; # matches a hh:mm:ss time format /[\d\s]/; # matches any digit or whitespace character /\w\W\w/; # matches a word char, followed by a @@ -957,6 +1046,16 @@ /end\./; # matches 'end.' /end[.]/; # same thing, matches 'end.' +=end original + + /\d\d:\d\d:\d\d/; # hh:mm:ss 形式の時間表記にマッチ + /[\d\s]/; # 数字または空白にマッチ + /\w\W\w/; # 非単語文字が続きさらに単語文字が続く + # 単語文字にマッチ + /..rt/; # 'rt' が続く任意の二文字にマッチ + /end\./; # 'end.' にマッチ + /end[.]/; # 同じこと。'end.' にマッチ + =begin original Because a period is a metacharacter, it needs to be escaped to match @@ -987,12 +1086,22 @@ これは単語を構成する文字と単語を構成しない文字の間 C<\w\W> や C<\W\w> の 境界にマッチします: +=begin original + $x = "Housecat catenates house and cat"; $x =~ /cat/; # matches cat in 'housecat' $x =~ /\bcat/; # matches cat in 'catenates' $x =~ /cat\b/; # matches cat in 'housecat' $x =~ /\bcat\b/; # matches 'cat' at end of string +=end original + + $x = "Housecat catenates house and cat"; + $x =~ /cat/; # 'housecat' の cat にマッチ + $x =~ /\bcat/; # 'catenates' の cat にマッチ + $x =~ /cat\b/; # 'housecat' の cat にマッチ + $x =~ /\bcat\b/; # 文字列の終端の'cat'にマッチ + =begin original Note in the last example, the end of the string is considered a word @@ -1021,15 +1130,32 @@ みなしたいでしょう。 ですから +=begin original + "" =~ /^$/; # matches "\n" =~ /^$/; # matches, $ anchors before "\n" +=end original + + "" =~ /^$/; # マッチ + "\n" =~ /^$/; # マッチ。"\n" は無視される + +=begin original + "" =~ /./; # doesn't match; it needs a char "" =~ /^.$/; # doesn't match; it needs a char "\n" =~ /^.$/; # doesn't match; it needs a char other than "\n" "a" =~ /^.$/; # matches "a\n" =~ /^.$/; # matches, $ anchors before "\n" +=end original + + "" =~ /./; # マッチしない。キャラクタが必要 + "" =~ /^.$/; # マッチしない。キャラクタが必要 + "\n" =~ /^.$/; # マッチしない。"\n"以外のキャラクタが必要 + "a" =~ /^.$/; # マッチする + "a\n" =~ /^.$/; # マッチする。"\n" は無視される + =begin original This behavior is convenient, because we usually want to ignore @@ -1137,16 +1263,34 @@ $x = "There once was a girl\nWho programmed in Perl\n"; +=begin original + $x =~ /^Who/; # doesn't match, "Who" not at start of string $x =~ /^Who/s; # doesn't match, "Who" not at start of string $x =~ /^Who/m; # matches, "Who" at start of second line $x =~ /^Who/sm; # matches, "Who" at start of second line +=end original + + $x =~ /^Who/; # マッチしない。"Who" は文字列の先頭にはない + $x =~ /^Who/s; # マッチしない。"Who" は文字列の先頭にはない + $x =~ /^Who/m; # マッチする。"Who" は二行目の先頭にある + $x =~ /^Who/sm; # マッチする。"Who" は二行目の先頭にある + +=begin original + $x =~ /girl.Who/; # doesn't match, "." doesn't match "\n" $x =~ /girl.Who/s; # matches, "." matches "\n" $x =~ /girl.Who/m; # doesn't match, "." doesn't match "\n" $x =~ /girl.Who/sm; # matches, "." matches "\n" +=end original + + $x =~ /girl.Who/; # マッチしない。"." は "\n" にマッチしない + $x =~ /girl.Who/s; # マッチする。"." は "\n"にマッチする + $x =~ /girl.Who/m; # マッチしない。"." は "\n" にマッチしない + $x =~ /girl.Who/sm; # マッチする。"." は "\n"にマッチする + =begin original Most of the time, the default behavior is what is wanted, but C<//s> and @@ -1157,22 +1301,43 @@ =end original -ほとんどの場合、デフォルトの動作が望んでいるものですが、C<//s> や C<//m> は -とても便利なものです。 +ほとんどの場合、デフォルトの動作が望んでいるものですが、C<//s> や +C<//m> はとても便利なものです。 もし C<//m> を使っているのなら、文字列の先頭は C<\A> で マッチさせることができ、文字列の末尾はアンカー C<\Z> (C<$> と同じように、 末尾と末尾にある改行の直前にマッチします) や C<\z> (末尾にのみマッチ)で マッチさせることができます: +=begin original + $x =~ /^Who/m; # matches, "Who" at start of second line $x =~ /\AWho/m; # doesn't match, "Who" is not at start of string +=end original + + $x =~ /^Who/m; # マッチする。 "Who" は二行目の先頭にある + $x =~ /\AWho/m; # マッチしない。"Who" は文字列の先頭にはない + +=begin original + $x =~ /girl$/m; # matches, "girl" at end of first line $x =~ /girl\Z/m; # doesn't match, "girl" is not at end of string +=end original + + $x =~ /girl$/m; # マッチする。"girl" は一行目の末尾にある + $x =~ /girl\Z/m; # マッチしない。"girl" は文字列の末尾にはない + +=begin original + $x =~ /Perl\Z/m; # matches, "Perl" is at newline before end $x =~ /Perl\z/m; # doesn't match, "Perl" is not at end of string +=end original + + $x =~ /Perl\Z/m; # マッチする。"Perl" は末尾の直前にある改行の前にある + $x =~ /Perl\z/m; # マッチしない。"Perl" は文字列の末尾にはない + =begin original We now know how to create choices among classes of characters in a @@ -1212,9 +1377,16 @@ 移動します。 幾つか例を挙げましょう: +=begin original + "cats and dogs" =~ /cat|dog|bird/; # matches "cat" "cats and dogs" =~ /dog|cat|bird/; # matches "cat" +=end original + + "cats and dogs" =~ /cat|dog|bird/; # "cat" にマッチ + "cats and dogs" =~ /dog|cat|bird/; # "cat" にマッチ + =begin original Even though C<dog> is the first alternative in the second regexp, @@ -1225,9 +1397,16 @@ 二番目の正規表現において最初の選択肢が C<dog> であるにもかかわらず、 C<cat> が文字列で最初に現れるマッチ対象です。 +=begin original + "cats" =~ /c|ca|cat|cats/; # matches "c" "cats" =~ /cats|cat|ca|c/; # matches "cats" +=end original + + "cats" =~ /c|ca|cat|cats/; # "c" にマッチ + "cats" =~ /cats|cat|ca|c/; # "cats" にマッチ + =begin original Here, all the alternatives match at the first string position, so the @@ -1237,12 +1416,21 @@ =end original -ここではすべての選択肢が最初の位置でマッチするので、最初の選択肢がマッチ対象となります。 -もし一部の選択肢が他の選択肢を縮めたものであるならば、マッチのチャンスを与えるために最も長いものを最初に置きます。 +ここではすべての選択肢が最初の位置でマッチするので、最初の選択肢が +マッチ対象となります。 +もし一部の選択肢が他の選択肢を縮めたものであるならば、マッチのチャンスを +与えるために最も長いものを最初に置きます。 + +=begin original "cab" =~ /a|b|c/ # matches "c" # /a|b|c/ == /[abc]/ +=end original + + "cab" =~ /a|b|c/ # "c" にマッチ + # /a|b|c/ == /[abc]/ + =begin original The last example points out that character classes are like @@ -1301,19 +1489,44 @@ C<house> にマッチすることを意味します。 幾つか例を挙げましょう +=begin original + /(a|b)b/; # matches 'ab' or 'bb' /(ac|b)b/; # matches 'acb' or 'bb' /(^a|b)c/; # matches 'ac' at start of string or 'bc' anywhere /(a|[bc])d/; # matches 'ad', 'bd', or 'cd' +=end original + + /(a|b)b/; # 'ab' または 'bb' にマッチ + /(ac|b)b/; # 'acb' または 'bb' にマッチ + /(^a|b)c/; # 文字列の先頭にある 'ac' か任意の場所の'bc'にマッチ + /(a|[bc])d/; # 'ad', 'bd', 'cd' にマッチ + +=begin original + /house(cat|)/; # matches either 'housecat' or 'house' /house(cat(s|)|)/; # matches either 'housecats' or 'housecat' or # 'house'. Note groups can be nested. +=end original + + /house(cat|)/; # 'housecat' か 'house' にマッチ + /house(cat(s|)|)/; # 'housecats' か 'housecat' か 'house' のいずれかに + # マッチ。グループがネストできることに注意 + +=begin original + /(19|20|)\d\d/; # match years 19xx, 20xx, or the Y2K problem, xx "20" =~ /(19|20|)\d\d/; # matches the null alternative '()\d\d', # because '20\d\d' can't match +=end original + + /(19|20|)\d\d/; # 年を表す19xx, 20xx か 2000 年問題を持つ xx にマッチ + "20" =~ /(19|20|)\d\d/; # 空の選択肢 '()\d\d' にマッチ + # '20\d\d' はマッチできないから + =begin original Alternations behave the same way in groups as out of them: at a given @@ -1387,7 +1600,7 @@ =end original -文字列の最初の文字'a'から始めます。 +文字列の最初の文字 'a' から始めます。 =item 1 @@ -1398,7 +1611,7 @@ =end original -最初のグループの中の最初の選択肢'abd'を試します。 +最初のグループの中の最初の選択肢 'abd' を試します。 =item 2 @@ -1434,7 +1647,7 @@ =end original -'a'、'b'、'c'と続けてマッチします。 +'a', 'b', 'c' と続けてマッチします。 ここで最初のグループが満足されました。 $1 に 'abc' をセットします。 @@ -1471,7 +1684,7 @@ 正規表現中の 'f' は文字列中の 'e' にマッチしません。 行き止まりです。 -一文字後戻りして二番目のグループの二番目の選択肢'd'を取り出します。 +一文字後戻りして二番目のグループの二番目の選択肢 'd' を取り出します。 =item 8 @@ -1482,8 +1695,7 @@ =end original - - 'd'にマッチします。 +'d' にマッチします。 二番目のグループは満足されたので、$2 に 'd' をセットします。 =item 9 @@ -1981,10 +2193,18 @@ to extract the corresponding substrings, 代わりに@-と@+を使いましょう: (TBT) +=begin original + $` is the same as substr( $x, 0, $-[0] ) $& is the same as substr( $x, $-[0], $+[0]-$-[0] ) $' is the same as substr( $x, $+[0] ) +=end original + + $` は substr( $x, 0, $-[0] ) と同じです + $& は substr( $x, $-[0], $+[0]-$-[0] ) と同じです + $' は substr( $x, $+[0] ) と同じです + =head2 Non-capturing groupings (キャプチャしないグループ化) @@ -2036,7 +2256,8 @@ =end original -非キャプチャグループ化はsplit操作において不必要な要素を取り除くためにも使われますwhere parentheses are +非キャプチャグループ化はsplit操作において不必要な要素を取り除くためにも +使われます where parentheses are required for some reason: (TBT) @@ -2156,6 +2377,8 @@ 以下に幾つか例を挙げます: +=begin original + /[a-z]+\s+\d*/; # match a lowercase word, at least one space, and # any number of digits /(\w+)\s+\1/; # match doubled words of arbitrary length @@ -2166,6 +2389,18 @@ $year =~ /\d{2}(\d{2})?/; # same thing written differently. However, # this produces $1 and the other does not. +=end original + + /[a-z]+\s+\d*/; # 小文字の単語、幾つかの空白、それに続く任意の長さの + # 数字にマッチ + /(\w+)\s+\1/; # 任意の長さの単語の重複にマッチ + /y(es)?/i; # 'y', 'Y', または大小文字を無視して 'yes' にマッチ + $year =~ /\d{2,4}/; # 年が少なくとも2桁あるが最大でも4桁になるように + # する + $year =~ /\d{4}|\d{2}/; # もっと良い。3桁をはじく + $year =~ /\d{2}(\d{2})?/; # 同じことの違うやり方。しかし、この例では + # $1 を生成する + % simple_grep '^(\w+)\1$' /usr/dict/words # isn't this easier? beriberi booboo @@ -2186,7 +2421,7 @@ これらの量指定子のすべてで、Perl は正規表現のマッチが成功するのを許す範囲で 可能な限りの文字列をマッチさせようとします。 -したがって、C</a?.../> があったとき、Perl は最初にaがあるものとして +したがって、C</a?.../> があったとき、Perl は最初に C<a> があるものとして 正規表現のマッチを試みます。 もしそれが失敗したら、Perl は C<a> がないものとして正規表現のマッチを 試みます。 @@ -2401,7 +2636,8 @@ =end original -この例では、C<.?> は文字列の中で可能な限り早い場所での最大一文字、つまり C<programming> の中の C<'a'> をつかみとります。 +この例では、C<.?> は文字列の中で可能な限り早い場所での最大一文字、つまり +C<programming> の中の C<'a'> をつかみとります。 C<m{1,2}> は両方の C<m> にマッチする機会を与えられます。 最終的に、 @@ -2434,8 +2670,9 @@ 貪欲であることがよくない場合もあります。 文字列の最大の部分ではなく 最小の部分にマッチする量指定子が欲しいときが あります。 -この目的のために、Larry Wall は I<最小マッチ>(minimal match)もしくは -I<無欲>(non-greedy)な量指定子 C<??>, C<*?>, C<+?>, C<{}?> を作り出しました。 +この目的のために、Larry Wall は I<最小マッチ>(minimal match) あるいは +I<無欲な>(non-greedy) 量指定子 C<??>, C<*?>, C<+?>, C<{}?> を +作り出しました。 これらは通常の量指定子に C<?> を付け加えたもので、以下のような意味を 持ちます: @@ -2449,8 +2686,8 @@ =end original -C<a??> は: 空か'a'にマッチします。 -はじめに空を試し、それから'a'を試します。 +C<a??> は: 空か 'a' にマッチします。 +はじめに空を試し、それから 'a' を試します。 =item * @@ -2461,7 +2698,7 @@ =end original -C<a*?> は: 'a'のゼロ回以上の繰り返しにマッチします。 +C<a*?> は: 'a' のゼロ回以上の繰り返しにマッチします。 任意回の繰り返しができますが、可能な限り少ない回数になります。 =item * @@ -2473,7 +2710,7 @@ =end original -C<a+?> は: 'a'の一回以上の繰り返しにマッチします。 +C<a+?> は: 'a' の一回以上の繰り返しにマッチします。 一回以上の任意回の繰り返しができますが、可能な限り少ない回数になります。 =item * @@ -2670,8 +2907,7 @@ =end original - - 文字列の最初の文字't'で始まる。 +文字列の最初の文字't'で始まる。 =item 1 @@ -2682,8 +2918,8 @@ =end original - - 最初の量指定子 '.*' は文字列全体'the cat in the hat'にまずはじめにマッチする。 +最初の量指定子 '.*' は文字列全体'the cat in the hat'にまずはじめに +マッチする。 =item 2 @@ -2694,8 +2930,7 @@ =end original - - 正規表現要素'at'の'a'は文字列の末尾にマッチしない。 +正規表現要素 'at' の 'a' は文字列の末尾にマッチしない。 一文字後戻りする。 =item 3 @@ -2707,8 +2942,8 @@ =end original - - 正規表現要素'at'の'a'は文字列の最後の文字't'にマッチしないので、更に一文字後戻りする。 +正規表現要素 'at' の 'a' は文字列の最後の文字 't' にマッチしないので、 +更に一文字後戻りする。 =item 4 @@ -2718,8 +2953,7 @@ =end original - - ここで'a'と't'にマッチすることができる。 +ここで 'a' と 't' にマッチすることができる。 =item 5 @@ -2730,9 +2964,9 @@ =end original - - 三番目の要素'.*'に移る。 -文字列の末尾に位置していて、'.*'は 0回の繰り返しにマッチすることができるので空文字列をアサインする。 +三番目の要素 '.*' に移る。 +文字列の末尾に位置していて、'.*' は 0 回の繰り返しに +マッチすることができるので空文字列を代入する。 =item 6 @@ -2742,8 +2976,7 @@ =end original - - 完了! +完了! =back @@ -3101,6 +3334,8 @@ これを使うことによって、よりわかりやすい形式に正規表現を「拡張」することが できます +=begin original + /^ [+-]? # first, match an optional sign ( # then match integers or f.p. mantissas: @@ -3112,6 +3347,19 @@ ([eE][+-]?\d+)? # finally, optionally match an exponent $/x; +=end original + + /^ + [+-]? # まずはじめに、省略可能な符号にマッチ + ( # 続いて整数か f.p 仮数部にマッチ: + \d+\.\d+ # a.b 形式の仮数部 + |\d+\. # a. 形式の仮数部 + |\.\d+ # .b 形式の仮数部 + |\d+ # a 形式の整数 + ) + ([eE][+-]?\d+)? # 最後に省略可能な指数部にマッチ + $/x; + =begin original If whitespace is mostly irrelevant, how does one include space @@ -3130,6 +3378,8 @@ たとえば、Perl が符号と仮数部(もしくは整数部) の間に空白を置くことを 許すとすると、以下のように正規表現に加えることができます: +=begin original + /^ [+-]?\ * # first, match an optional sign *and space* ( # then match integers or f.p. mantissas: @@ -3141,6 +3391,19 @@ ([eE][+-]?\d+)? # finally, optionally match an exponent $/x; +=end original + + /^ + [+-]?\ * # まずはじめに、省略可能な符号と*スペース*にマッチ + ( # 続いて整数か f.p 仮数部にマッチ: + \d+\.\d+ # a.b 形式の仮数部 + |\d+\. # a. 形式の仮数部 + |\.\d+ # .b 形式の仮数部 + |\d+ # a 形式の整数 + ) + ([eE][+-]?\d+)? # 最後に、省略可能な指数部にマッチ + $/x; + =begin original In this form, it is easier to see a way to simplify the @@ -3153,6 +3416,8 @@ 選択肢 1, 2, 4 はすべて C<\d+> で始まっています。 ですからこれはまとめることができます: +=begin original + /^ [+-]?\ * # first, match an optional sign ( # then match integers or f.p. mantissas: @@ -3165,6 +3430,20 @@ ([eE][+-]?\d+)? # finally, optionally match an exponent $/x; +=end original + + /^ + [+-]?\ * # まずはじめに、省略可能な符号にマッチ + ( # 続いて整数か f.p. 仮数部にマッチ: + \d+ # はじめは… + ( + \.\d* # a.b形式もしくはa.形式の仮数部 + )? # ? はa形式の整数を考慮する + |\.\d+ # .b形式の仮数部 + ) + ([eE][+-]?\d+)? # 最後に、省略可能な指数部にマッチ + $/x; + =begin original or written in the compact form, @@ -3247,8 +3526,10 @@ =end original -これはコンピュータプログラムを書くにあたっての典型的なステップでもあります。 -正規表現はパターンを特定する小さなコンピュータ言語で書くプログラムであるので、このことはまさに当てはまります。 +これはコンピュータプログラムを書くにあたっての典型的なステップでも +あります。 +正規表現はパターンを特定する小さなコンピュータ言語で書く +プログラムであるので、このことはまさに当てはまります。 =head2 Using regular expressions in Perl @@ -3342,11 +3623,20 @@ すべての置換を行いたくないというのであれば、特殊なデリミタ C<m''> を使います: +=begin original + @pattern = ('Seuss'); while (<>) { print if m'@pattern'; # matches literal '@pattern', not 'Seuss' } +=end original + + @pattern = ('Seuss'); + while (<>) { + print if m'@pattern'; # 'Seuss' ではなくリテラルの '@pattern' にマッチ + } + =begin original Similar to strings, C<m''> acts like apostrophes on a regexp; all other @@ -3361,9 +3651,15 @@ もし正規表現が空文字列を評価したならば、その正規表現は I<最後に成功した> マッチにある正規表現が代わりに使われます。 +=begin original + "dog" =~ /d/; # 'd' matches "dogbert =~ //; # this matches the 'd' regexp used before +=end original + + "dog" =~ /d/; # 'd' にマッチ + "dogbert =~ //; # 直前に使われた正規表現である 'd' にマッチ =head3 Global matching @@ -3484,6 +3780,8 @@ C<\G> はコンテキストを考慮したマッチング(context-sensitive matching)を 容易にさせます。 +=begin original + $metric = 1; # use metric units ... $x = <FILE>; # read in measurement @@ -3497,6 +3795,21 @@ } $x =~ /\G\s+(widget|sprocket)/g; # continue processing +=end original + + $metric = 1; # metric ユニットを使う + ... + $x = <FILE>; # 測定のために読み込み + $x =~ /^([+-]?\d+)\s*/g; # 重さを取得 + $weight = $1; + if ($metric) { # エラーチェック + print "Units error!" unless $x =~ /\Gkg\./g; + } + else { + print "Units error!" unless $x =~ /\Glbs\./g; + } + $x =~ /\G\s+(widget|sprocket)/g; # 処理を続ける + =begin original The combination of C<//g> and C<\G> allows us to process the string a @@ -3644,12 +3957,16 @@ 正規表現と修飾子をここで使うことができます。 C<replacement> は Perlでのダブルクォートで囲まれた文字列で、 C<regexp> にマッチした文字列を置き換えるものです。 -C<=~> 演算子もまた C<s///> を伴った文字列に結びつけられるために使われます。 -C<$_> に対してマッチングを行う場合には、S<C<$_ =~>> は省略することができます。 -マッチに成功した場合には C<s///> は置換が行われた数を返し、失敗した場合には -偽を返します。 +C<=~> 演算子もまた C<s///> を伴った文字列に結びつけられるために +使われます。 +C<$_> に対してマッチングを行う場合には、S<C<$_ =~>> は省略することが +できます。 +マッチに成功した場合には C<s///> は置換が行われた数を返し、失敗した +場合には偽を返します。 幾つか例を挙げましょう: +=begin original + $x = "Time to feed the cat!"; $x =~ s/cat/hacker/; # $x contains "Time to feed the hacker!" if ($x =~ s/^(Time.*hacker)!$/$1 now!/) { @@ -3659,6 +3976,17 @@ $y =~ s/^'(.*)'$/$1/; # strip single quotes, # $y contains "quoted words" +=end original + + $x = "Time to feed the cat!"; + $x =~ s/cat/hacker/; # $x の内容は "Time to feed the hacker!" + if ($x =~ s/^(Time.*hacker)!$/$1 now!/) { + $more_insistent = 1; + } + $y = "'quoted words'"; + $y =~ s/^'(.*)'$/$1/; # シングルクォートを剥ぎ取る + # $y の内容は "quoted words" + =begin original In the last example, the whole string was matched, but only the part @@ -3678,6 +4006,8 @@ グローバル修飾子 C<s///g> を使うことで、文字列中のすべての正規表現に マッチする検索と置換を行います: +=begin original + $x = "I batted 4 for 4"; $x =~ s/4/four/; # doesn't do it all: # $x contains "I batted four for 4" @@ -3685,6 +4015,15 @@ $x =~ s/4/four/g; # does it all: # $x contains "I batted four for four" +=end original + + $x = "I batted 4 for 4"; + $x =~ s/4/four/; # すべてにはマッチしない: + # $x の内容は "I batted four for 4" + $x = "I batted 4 for 4"; + $x =~ s/4/four/g; # すべてにマッチ: + # $x の内容は "I batted four for four" + =begin original If you prefer 'regex' over 'regexp' in this tutorial, you could use @@ -3740,11 +4079,20 @@ あるときに便利です。 以下の例はある行の文字の出現頻度を数えます: +=begin original + $x = "Bill the cat"; $x =~ s/(.)/$chars{$1}++;$1/eg; # final $1 replaces char with itself print "frequency of '$_' is $chars{$_}\n" foreach (sort {$chars{$b} <=> $chars{$a}} keys %chars); +=end original + + $x = "Bill the cat"; + $x =~ s/(.)/$chars{$1}++;$1/eg; # 最終的に $1 はそれ自身の文字に置換される + print "frequency of '$_' is $chars{$_}\n" + foreach (sort {$chars{$b} <=> $chars{$a}} keys %chars); + =begin original This prints @@ -3929,11 +4277,20 @@ これらもパターンで使えます。 C<\l> や C<\u> は続く文字をそれぞれ小文字と大文字に変換します: +=begin original + $x = "perl"; $string =~ /\u$x/; # matches 'Perl' in $string $x = "M(rs?|s)\\."; # note the double backslash $string =~ /\l$x/; # matches 'mr.', 'mrs.', and 'ms.', +=end original + + $x = "perl"; + $string =~ /\u$x/; # $string の中の 'Perl' にマッチ + $x = "M(rs?|s)\\."; # 二重のバックスラッシュに注意 + $string =~ /\l$x/; # 'mr.', 'mrs.', 'ms.' にマッチ + =begin original A C<\L> or C<\U> indicates a lasting conversion of case, until @@ -3945,11 +4302,20 @@ terminated by C<\E> or thrown over by another C<\U> or C<\L>: (TBT) +=begin original + $x = "This word is in lower case:\L SHOUT\E"; $x =~ /shout/; # matches $x = "I STILL KEYPUNCH CARDS FOR MY 360" $x =~ /\Ukeypunch/; # matches punch card string +=end original + + $x = "This word is in lower case:\L SHOUT\E"; + $x =~ /shout/; # マッチする + $x = "I STILL KEYPUNCH CARDS FOR MY 360" + $x =~ /\Ukeypunch/; # パンチカード文字列にマッチする + =begin original If there is no C<\E>, case is converted until the end of the @@ -4066,19 +4432,28 @@ =end original -あなたが必要なUnicode文字を十六進数で表記することや、別の誰かが十六進表記の -Unicode正規表現を解読することは、機械語でプログラミングすることを -楽しむかのようです。 +あなたが必要なUnicode文字を十六進数で表記することや、別の誰かが +16 進表記の Unicode 正規表現を解読することは、機械語で +プログラミングすることを楽しむかのようです。 ですから、Unicode文字を指定する別の方法として C<\N{name}> のような I<名前付き文字> エスケープシーケンスを使うものがあります。 C<name> は Unicode 文字に対する名前であって、Unicode standard で 定義されているものです。 -たとえば、水星を表す占星術記号を表したりマッチさせるために以下のようにします +たとえば、水星を表す占星術記号を表したりマッチさせるために +以下のようにします + +=begin original use charnames ":full"; # use named chars with Unicode full names $x = "abc\N{MERCURY}def"; $x =~ /\N{MERCURY}/; # matches +=end original + + use charnames ":full"; # Unicodeのフルネームで名前つき文字を使う + $x = "abc\N{MERCURY}def"; + $x =~ /\N{MERCURY}/; # マッチ + =begin original One can also use short names or restrict names to a certain alphabet: @@ -4143,6 +4518,8 @@ C<\P{name}> は C<\p{name}> の反対の意味を持つ文字クラスです。 たとえば小文字や大文字の文字にマッチさせるには +=begin original + use charnames ":full"; # use named chars with Unicode full names $x = "BOB"; $x =~ /^\p{IsUpper}/; # matches, uppercase char class @@ -4150,6 +4527,15 @@ $x =~ /^\p{IsLower}/; # doesn't match, lowercase char class $x =~ /^\P{IsLower}/; # matches, char class sans lowercase +=end original + + use charnames ":full"; # Unicodeのフルネームで名前つき文字を使う + $x = "BOB"; + $x =~ /^\p{IsUpper}/; # マッチする。大文字の文字クラス + $x =~ /^\P{IsUpper}/; # マッチしない。文字クラスは大文字以外 + $x =~ /^\p{IsLower}/; # マッチしない。小文字の文字クラス + $x =~ /^\P{IsLower}/; # マッチする。文字クラスは小文字以外 + =begin original Here is the association between some Perl named classes and the @@ -4192,8 +4578,8 @@ 数字以外の\P{Nd}のように、公式なUncodeクラス名を C<\p> や C<\P> を 使って使用することができます。 C<name> がただ一文字であった場合には、ブレースは省略することができます。 -たとえば、C<\pM> は Unicode の 'marks' の文字クラスで、アクセント記号などが -当てはまります。 +たとえば、C<\pM> は Unicode の 'marks' の文字クラスで、 +アクセント記号などが当てはまります。 リスト全部については L<perlunicode> を参照してください。 =begin original @@ -4241,7 +4627,8 @@ Unicodeのフルネームを使った S<C<A + COMBINING RING>> は、 C<A> とそれに続く結合文字 S<C<COMBINING RING>> で、これはデンマーク語の オングストロームという単語の中にある丸が上についたAです。 -C<\X> は C<\PM\pM*}> と等価で、一つ以上のマークの続いたマークでないものです。 +C<\X> は C<\PM\pM*}> と等価で、一つ以上のマークの続いた後の、 +マークでないものです。 =begin original @@ -4275,15 +4662,27 @@ =end original -これで十分でないかのように、PerlではPOSIX形式の文字クラスも定義しています。 -これらは[:name:]という形式で、nameは POSIXのクラスの名前です。 -POSIXクラスにはalpha、alnum、ascii、 cntrl、digit、graph、lower、print、punct、space、 upper、xdigitがあり、さらに二つの拡張 word(\wにマッチする Perlの拡張)とblank(GNUによる拡張)があります。 -utf8が使われている場合には、これらのクラスはそれぞれを表すperlのUnicodeクラスに等価なものとして定義されます: たとえば[:upper:]は\p{IsUpper}と同じことです。 -しかしながら、POSIX文字クラスはutf8を必要とはしません。 - [:digit:], [:word:], [:space:]はそれぞれなじみ深い\d、\w、\sに対応します。 -POSIXクラスを否定するには ^を名前の前に置きます。 -ですから、[:^digit:] は\Dに対応し、 utf8の元での\P{IsDigit}になります。 -Unicodeの文字クラスと POSIXの文字クラスは\dのように使うことができますが、 POSIXの文字クラスは文字クラスの中でだけ使うことができます。 +これで十分でないかのように、Perl では POSIX 形式の文字クラスも +定義しています。 +これらは C<[:name:]> という形式で、C<name> は POSIX クラスの名前です。 +POSIX クラスには C<alpha>, C<alnum>, C<ascii>, C<cntrl>, C<digit>, +C<graph>, C<lower>, C<print>, C<punct>, C<space>, C<upper>, +C<xdigit> があり、さらに二つの拡張である C<word> (\w にマッチする +Perlの拡張)と C<blank>(GNU による拡張)があります。 +C<utf8> が使われている場合には、これらのクラスはそれぞれを表す Perl の +Unicode クラスに等価なものとして定義されます: たとえば C<[:upper:]> は +C<\p{IsUpper}> と同じことです。 +しかしながら、POSIX 文字クラスは C<utf8> を必要とはしません。 +C<[:digit:]>, C<[:word:]>, C<[:space:]> はそれぞれなじみ深い +C<\d>, C<\w>, C<\s> に対応します。 +POSIX クラスを否定するには C<^> を名前の前に置きます。 +ですから、C<[:^digit:]> は C<\D> に対応し、 C<utf8> の元での +C<\P{IsDigit}> になります。 +Unicode の文字クラスと POSIX の文字クラスは C<\d> のように +使うことができますが、 POSIX の文字クラスは文字クラスの中でだけ +使うことができます。 + +=begin original /\s+[abc[:digit:]xyz]\s*/; # match a,b,c,x,y,z, or a digit /^=item\s[[:digit:]]/; # match '=item', @@ -4293,17 +4692,28 @@ /^=item\s\p{IsDigit}/; # match '=item', # followed by a space and a digit +=end original + + /\s+[abc[:digit:]xyz]\s*/; # a,b,c,x,y,z, または数字にマッチ + /^=item\s[[:digit:]]/; # スペースと数字が後続する '=item' + # にマッチ + use charnames ":full"; + /\s+[abc\p{IsDigit}xyz]\s+/; # a,b,c,x,y,z, または数字にマッチ + /^=item\s\p{IsDigit}/; # スペースと数字が後続する '=item' + # にマッチ + =begin original Whew! That is all the rest of the characters and character classes. =end original -これが文字と文字クラスで残っていたことです。 +ふう。 +これが文字と文字クラスで残っていたこと全てです。 =head2 Compiling and saving regular expressions -(正規表現のコンパイルとセーブ) +(正規表現のコンパイルと保管) =begin original @@ -4324,8 +4734,14 @@ C<qr/string/> は C<string> を正規表現としてコンパイルして結果を変数に 代入することのできる形式へと変換します: +=begin original + $reg = qr/foo+bar?/; # reg contains a compiled regexp +=end original + + $reg = qr/foo+bar?/; # reg はコンパイル済み正規表現を保持する + =begin original Then C<$reg> can be used as a regexp: @@ -4334,10 +4750,18 @@ C<$reg> は正規表現として使うことができます: +=begin original + $x = "fooooba"; $x =~ $reg; # matches, just like /foo+bar?/ $x =~ /$reg/; # same thing, alternate form +=end original + + $x = "fooooba"; + $x =~ $reg; # マッチする。/foo+bar?/ と同様 + $x =~ /$reg/; # 同じことを別の形式で + =begin original C<$reg> can also be interpolated into a larger regexp: @@ -4346,8 +4770,14 @@ C<$reg> はより大きな正規表現の中で展開することもできます: +=begin original + $x =~ /(abc)?$reg/; # still matches +=end original + + $x =~ /(abc)?$reg/; # これもマッチする + =begin original As with the matching operator, the regexp quote can use different @@ -4411,10 +4841,12 @@ コンパイル済み正規表現を配列 C<@compiled> に格納することで、 再コンパイルすることなく正規表現を使うことができ、これにより -速度を犠牲にすることなく融通性を手に入れることができました。 +速度を犠牲にすることなく柔軟性を手に入れることができました。 =head2 Composing regular expressions at runtime +(実行時に正規表現を構成する) + =begin original Backtracking is more efficient than repeated tries with different regular @@ -4537,7 +4969,7 @@ =end original -このセクションのはじめで、Perlの I<拡張パターン>(extended patterns)の +このセクションのはじめで、Perl の I<拡張パターン>(extended patterns)の セットについて述べると言いました。 以下に述べるのは、伝統的な正規表現構文を拡張して、パターンマッチングに おいて新しい強力なツールを提供するものです。 @@ -4585,6 +5017,8 @@ 埋め込むこともできます。 例を挙げましょう +=begin original + /(?i)yes/; # match 'yes' case insensitively /yes/i; # same thing /(?x)( # freeform version of an integer regexp @@ -4593,6 +5027,16 @@ ) /x; +=end original + + /(?i)yes/; # 大小文字の違いを無視して 'yes' にマッチ + /yes/i; # 同じこと + /(?x)( # 自由形式の整数にマッチする正規表現 + [+-]? # 省略可能な符号 + \d+ # 数字の並びにマッチ + ) + /x; + =begin original Embedded modifiers can have two important advantages over the usual @@ -4625,14 +5069,18 @@ =end original -二番目の利点は、埋め込み修飾子(except C<//k>, which -modifies the entire regexp) +二番目の利点は、埋め込み修飾子(正規表現全体を修正する C<//k> を除きます) はそれが埋め込まれたグループの中にある正規表現にだけ影響するということです。 このため、グループ化を修飾子の影響を局所化するために使うことができます: -(TBT) + +=begin original /Answer: ((?i)yes)/; # matches 'Answer: yes', 'Answer: YES', etc. +=end original + + /Answer: ((?i)yes)/; # 'Answer: yes', 'Answer: YES' などにマッチ + =begin original Embedded modifiers can also turn off any modifiers already present @@ -4642,7 +5090,8 @@ =end original -埋め込み修飾子は C<(?-i)> のようにして任意の修飾子を無効にすることもできます。 +埋め込み修飾子は C<(?-i)> のようにして任意の修飾子を無効にすることも +できます。 修飾子は一つの式にまとめることもでき、たとえば C<(?s-i)> は 単一行モードを有効にして大小文字の違いを無視ししないようにします。 @@ -4751,6 +5200,8 @@ C<< (?<=fixed-regexp) >> で表されます。 幾つか例を挙げましょう +=begin original + $x = "I catch the housecat 'Tom-cat' with catnip"; $x =~ /cat(?=\s)/; # matches 'cat' in 'housecat' @catwords = ($x =~ /(?<=\s)cat\w+/g); # matches, @@ -4760,6 +5211,16 @@ $x =~ /(?<=\s)cat(?=\s)/; # doesn't match; no isolated 'cat' in # middle of $x +=end original + + $x = "I catch the housecat 'Tom-cat' with catnip"; + $x =~ /cat(?=\s)/; # 'housecat'の'cat'にマッチ + @catwords = ($x =~ /(?<=\s)cat\w+/g); # マッチする + # $catwords[0] = 'catch' + # $catwords[1] = 'catnip' + $x =~ /\bcat\b/; # 'Tom-cat'の'cat'にマッチ + $x =~ /(?<=\s)cat(?=\s)/; # マッチしない。$xの中間に 'cat' はない + =begin original Note that the parentheses in C<(?=regexp)> and C<< (?<=regexp) >> are @@ -4780,18 +5241,28 @@ したがって、二番目の正規表現ではキャプチャされた部分文字列は 正規表現全体に対応するものになります。 先読み表明 C<(?=regexp)> には任意の正規表現を使うことができますが、 -戻り読み表明 C<< (?<=fixed-regexp) >> は固定長の正規表現、たとえば固定長の -文字並びでのみ使うことができます。 -このため、C<< (?<=(ab|bc)) >> は大丈夫ですが C<< (?<=(ab)*) >>は使えません。 +戻り読み表明 C<< (?<=fixed-regexp) >> は固定長の正規表現、たとえば +固定長の文字並びでのみ使うことができます。 +このため、C<< (?<=(ab|bc)) >> は大丈夫ですが C<< (?<=(ab)*) >> は +使えません。 先読み表明と戻り読み表明の否定形はそれぞれ C<(?!regexp)> と C<< (?<!fixed-regexp) >> で表されます。 これらはその正規表現がマッチしなかったときに真となります。 +=begin original + $x = "foobar"; $x =~ /foo(?!bar)/; # doesn't match, 'bar' follows 'foo' $x =~ /foo(?!baz)/; # matches, 'baz' doesn't follow 'foo' $x =~ /(?<!\s)foo/; # matches, there is no \s before 'foo' +=end original + + $x = "foobar"; + $x =~ /foo(?!bar)/; # マッチしない。'bar' が 'foo' に続いている + $x =~ /foo(?!baz)/; # マッチする。'baz' は 'foo' に続いていない + $x =~ /(?<!\s)foo/; # マッチする。\s は 'foo' の前にない + =begin original The C<\C> is unsupported in lookbehind, because the already @@ -4851,9 +5322,16 @@ 独立部分式は C<< (?>regexp) >> で表されます。 これの振る舞いを通常の正規表現を使って説明しましょう: +=begin original + $x = "ab"; $x =~ /a*ab/; # matches +=end original + + $x = "ab"; + $x =~ /a*ab/; # マッチする + =begin original This obviously matches, but in the process of matching, the @@ -4879,8 +5357,14 @@ 独立部分式を使うと対照的に: +=begin original + $x =~ /(?>a*)ab/; # doesn't match! +=end original + + $x =~ /(?>a*)ab/; # マッチしない! + =begin original The independent subexpression C<< (?>a*) >> doesn't care about the rest @@ -4900,10 +5384,18 @@ 結果として正規表現全体のマッチングは失敗します。 同様の動作が、完全に独立した正規表現においても発生します: +=begin original + $x = "ab"; $x =~ /a*/g; # matches, eats an 'a' $x =~ /\Gab/g; # doesn't match, no 'a' available +=end original + + $x = "ab"; + $x =~ /a*/g; # マッチする 'a' を食い取る + $x =~ /\Gab/g; # マッチしない。'a' がない + =begin original Here C<//g> and C<\G> create a 'tag team' handoff of the string from @@ -4933,9 +5425,16 @@ 考えてみましょう。 それは以下のような正規表現になります: +=begin original + $x = "abc(de(fg)h"; # unbalanced parentheses $x =~ /\( ( [^()]+ | \([^()]*\) )+ \)/x; +=end original + + $x = "abc(de(fg)h"; # 対応の取れていないかっこ + $x =~ /\( ( [^()]+ | \([^()]*\) )+ \)/x; + =begin original The regexp matches an open parenthesis, one or more copies of an @@ -4998,9 +5497,10 @@ =end original -I<条件式> (conditional expression )はif-the-elseの形式の文で、何らかの +I<条件式> (conditional expression) は if-the-else の形式の文で、何らかの 条件に基づいてどちらのパターンをマッチさせるかを選択できます。 -条件式には二つのタイプがあります: C<(?(condition)yes-regexp)> と C<(?(condition)yes-regexp|no-regexp)> です。 +条件式には二つのタイプがあります: C<(?(condition)yes-regexp)> と +C<(?(condition)yes-regexp|no-regexp)> です。 C<(?(condition)yes-regexp)> は Perl の S<C<'if () {}'>> 文のようなものです。 もし C<condition> が真であれば、C<yes-regexp> がマッチの対象となります。 C<condition> が偽であった場合、C<yes-regexp> はスキップされて、 @@ -5243,7 +5743,8 @@ 通常、正規表現は Perl の式の一部です。 I<コード評価> (code evaluation) 式は任意のPerlのコードを正規表現の 一部として使うことができるようにします。 -コード評価式は C<(?{code})> で表され、I<code> は Perl の文である文字列です。 +コード評価式は C<(?{code})> で表され、I<code> は Perl の文である +文字列です。 =begin original @@ -5281,12 +5782,22 @@ 変数 C<$^R> は正規表現の後の部分のコード式で使うことができます。 以下に単純な例を挙げます: +=begin original + $x = "abcdef"; $x =~ /abc(?{print "Hi Mom!";})def/; # matches, # prints 'Hi Mom!' $x =~ /aaa(?{print "Hi Mom!";})def/; # doesn't match, # no 'Hi Mom!' +=end original + + $x = "abcdef"; + $x =~ /abc(?{print "Hi Mom!";})def/; # マッチする + # 'Hi Mom!' を主力 + $x =~ /aaa(?{print "Hi Mom!";})def/; # マッチしない + # 'Hi Mom!'は出力されない + =begin original Pay careful attention to the next example: @@ -5295,10 +5806,18 @@ 次の例に注目してください: +=begin original + $x =~ /abc(?{print "Hi Mom!";})ddd/; # doesn't match, # no 'Hi Mom!' # but why not? +=end original + + $x =~ /abc(?{print "Hi Mom!";})ddd/; # マッチしない。 + # 'Hi Mom!' は出力されない + # でもなぜ? + =begin original At first glance, you'd think that it shouldn't print, because obviously @@ -5312,9 +5831,16 @@ マッチするものではないからです。 しかし次の例: +=begin original + $x =~ /abc(?{print "Hi Mom!";})[d]dd/; # doesn't match, # but _does_ print +=end original + + $x =~ /abc(?{print "Hi Mom!";})[d]dd/; # マッチしない。 + # しかし出力「される」 + =begin original Hmm. What happened here? If you've been following along, you know that @@ -5325,8 +5851,11 @@ =end original ふーむ。 -何が起きたのでしょう? 先のパターンが効果としては最後のものと同じであることをあなたは知っています -- 文字クラスの中に閉じ込められた d はマッチを変えるものではありません。 -では、なぜ最初のパターンは出力されないのに二番目のものは出力されたのでしょう? +何が起きたのでしょう? 先のパターンが効果としては最後のものと +同じであることをあなたは知っています -- 文字クラスの中に閉じ込められた +d はマッチを変えるものではありません。 +では、なぜ最初のパターンは出力されないのに二番目のものは +出力されたのでしょう? =begin original @@ -5344,7 +5873,7 @@ =end original その答えは正規表現エンジンが行う最適化にあります。 -最初のケースでは。 +最初のケースでは、 エンジンが見ているものは普通の古い文字(C<?{}> 構造は別として) です。 パターンを実際に実行するよりも前にターゲット文字列が 'ddd' という 文字列を含んでいないことがわかるくらい賢いのです。 @@ -5370,7 +5899,9 @@ =end original -More fun with C<?{}>: +C<?{}> でもっと楽しいことが起きます: + +=begin original $x =~ /(?{print "Hi Mom!";})/; # matches, # prints 'Hi Mom!' @@ -5379,6 +5910,15 @@ $x =~ /(?{$c = 1;})(?{print "$^R";})/; # matches, # prints '1' +=end original + + $x =~ /(?{print "Hi Mom!";})/; # マッチする + # 'Hi Mom!' を出力 + $x =~ /(?{$c = 1;})(?{print "$c";})/; # マッチする + # '1' を出力 + $x =~ /(?{$c = 1;})(?{print "$^R";})/; # マッチする + # '1' を出力 + =begin original The bit of magic mentioned in the section title occurs when the regexp @@ -5390,7 +5930,7 @@ =end original -このセクションのタイトルにある The bit of magic というのは +このセクションのタイトルにある「ちょっとした魔法」というのは マッチのために検索処理をしているときのバックトラックが 起きたときのことを言っています。 もしバックトラックがコード式をまたいで発生して、C<local> によって @@ -5398,6 +5938,8 @@ 巻き戻されます! したがって、グループの中にある文字の数を数えたい場合には +=begin original + $x = "aaaa"; $count = 0; # initialize 'a' count $c = "bob"; # test if $c gets clobbered @@ -5410,13 +5952,27 @@ /x; print "'a' count is $count, \$c variable is '$c'\n"; +=end original + + $x = "aaaa"; + $count = 0; # 'a' のカウントを初期化する + $c = "bob"; # $c が上書きされているかを調べる + $x =~ /(?{local $c = 0;}) # カウントを初期化 + ( a # 'a' にマッチ + (?{local $c = $c + 1;}) # カウントをインクリメント + )* # これを任意回繰り返すが + aa # 最後に 'aa' にマッチ + (?{$count = $c;}) # ローカルの $c を $count にコピー + /x; + print "'a' count is $count, \$c variable is '$c'\n"; + =begin original This prints =end original -のようにすることができ、これは +のようにすることができ、これは以下を表示します 'a' count is 2, $c variable is 'bob' @@ -5481,6 +6037,8 @@ 以下の例は、条件にコード式を使って英語の 'the' か ドイツ語の 'der|die|das' にマッチさせるものです: +=begin original + $lang = 'DE'; # use German ... $text = "das"; @@ -5493,6 +6051,20 @@ ) /xi; +=end original + + $lang = 'DE'; # ドイツ語を使う + ... + $text = "das"; + print "matched\n" + if $text =~ /(?(?{ + $lang eq 'EN'; # 言語は英語か? + }) + the | # そうなら 'the' にマッチ + (der|die|das) # そうでないなら 'der|die|das' にマッチ + ) + /xi; + =begin original Note that the syntax here is C<(?(?{...})yes-regexp|no-regexp)>, not @@ -5502,7 +6074,8 @@ =end original -ここでの構文が C<(?((?{...}))yes-regexp|no-regexp)> ではなく C<(?(?{...})yes-regexp|no-regexp)> であることに注意してください。 +ここでの構文が C<(?((?{...}))yes-regexp|no-regexp)> ではなく +C<(?(?{...})yes-regexp|no-regexp)> であることに注意してください。 言い換えれば、コード式の場合には条件を囲む余計なかっこは いらないということです。 @@ -5516,15 +6089,32 @@ コード式を変数展開と共に使おうとしたならば、Perl は あなたを驚かせるかもしれません: +=begin original + $bar = 5; $pat = '(?{ 1 })'; /foo(?{ $bar })bar/; # compiles ok, $bar not interpolated /foo(?{ 1 })$bar/; # compile error! /foo${pat}bar/; # compile error! +=end original + + $bar = 5; + $pat = '(?{ 1 })'; + /foo(?{ $bar })bar/; # コンパイル ok。$barは展開されない + /foo(?{ 1 })$bar/; # コンパイルエラー! + /foo${pat}bar/; # コンパイルエラー! + +=begin original + $pat = qr/(?{ $foo = 1 })/; # precompile code regexp /foo${pat}bar/; # compiles ok +=end original + + $pat = qr/(?{ $foo = 1 })/; # コード正規表現をプリコンパイル + /foo${pat}bar/; # コンパイル ok + =begin original If a regexp has (1) code expressions and interpolating variables, or @@ -5557,10 +6147,18 @@ ユーザーからの入力を取り、それをダイレクトに変数に押し込むから 危険なのです。 +=begin original + $regexp = <>; # read user-supplied regexp $chomp $regexp; # get rid of possible newline $text =~ /$regexp/; # search $text for the $regexp +=end original + + $regexp = <>; # ユーザーが提供する正規表現を読み込む + $chomp $regexp; # 改行があれば取り除く + $text =~ /$regexp/; # $text から $regexp を探し出す + =begin original If the C<$regexp> variable contains a code expression, the user could @@ -5585,12 +6183,22 @@ もし悪意あるユーザーを考慮しないのであれば、S<C<use re 'eval'>>を 実行することによってセキュリティチェックをバイパスすることが可能です: +=begin original + use re 'eval'; # throw caution out the door $bar = 5; $pat = '(?{ 1 })'; /foo(?{ 1 })$bar/; # compiles ok /foo${pat}bar/; # compiles ok +=end original + + use re 'eval'; # 注意を無視する + $bar = 5; + $pat = '(?{ 1 })'; + /foo(?{ 1 })$bar/; # コンパイル ok + /foo${pat}bar/; # コンパイル ok + =begin original Another form of code expression is the I<pattern code expression>. @@ -5605,11 +6213,19 @@ 正規表現として扱われ、即座にマッチに使われる点が異なります。 単純な例を挙げましょう +=begin original + $length = 5; $char = 'a'; $x = 'aaaaabb'; $x =~ /(??{$char x $length})/x; # matches, there are 5 of 'a' +=end original + + $length = 5; + $char = 'a'; + $x = 'aaaaabb'; + $x =~ /(??{$char x $length})/x; # マッチする。5個の 'a'がある =begin original @@ -5803,10 +6419,18 @@ 変数展開とコード式を共存させることを許可するプラグマが登場しています。 他のプラグマには以下のものがあります +=begin original + use re 'taint'; $tainted = <>; @parts = ($tainted =~ /(\w+)\s+(\w+)/; # @parts is now tainted +=end original + + use re 'taint'; + $tainted = <>; + @parts = ($tainted =~ /(\w+)\s+(\w+)/; # @parts は汚染されている + =begin original The C<taint> pragma causes any substrings from a match with a tainted @@ -5828,12 +6452,26 @@ プラグマ C<taint> と C<eval> は両方ともレキシカルスコープで、その プラグマを囲むブロックの最後までしか影響が及びません。 +=begin original + use re 'debug'; /^(.*)$/s; # output debugging info +=end original + + use re 'debug'; + /^(.*)$/s; # デバッグ情報を出力する + +=begin original + use re 'debugcolor'; /^(.*)$/s; # output debugging info in living color +=end original + + use re 'debugcolor'; + /^(.*)$/s; # デバッグ情報を色つきで出力する + =begin original The global C<debug> and C<debugcolor> pragmas allow one to get @@ -5847,7 +6485,7 @@ C<debug> プラグマと C<debugcolor> プラグマは正規表現のコンパイルと 実行に関する詳細なデバッグ情報を提供します。 C<debugcolor> は C<debug> と同じですが、デバッグ情報を色付きで -(termcapのカラーシーケンスを出力することのできる)ターミナルに出力します。 +(termcap のカラーシーケンスを出力することのできる)ターミナルに出力します。 以下は出力の例です: % perl -e 'use re "debug"; "abc" =~ /a*b+c/;' @@ -6065,8 +6703,6 @@ Haworth, Ronald J Kimball, and Joe Smith for all their helpful comments. -=cut - =begin meta Created: KIMURA Koichi @@ -6074,3 +6710,5 @@ =end meta +=cut +