<パターンマッチング>
パターンを単純に指定したのでは、1つの演算子につき1つのパターンしか検索できず、これでは効率が悪すぎる。 そこで、1つの演算子で複数のパターンを検索できるようにパターンを多様化させる記法が存在する。 これが正規表現(Regular Expression)である。
reg.pl :
パターンマッチ演算子の末尾に"g"(global)を付けると"グローバルマッチング"を行う。 通常のマッチングは、文字列の先頭から順次検索していきマッチした時点で検索を止めるが、 グローバルマッチの場合、一致するもの全てを捜し出す。
さて、この例では、分かり易くするために m// ではなく s/// を用いた。
同じ文字列のコピー4つに対しそれぞれ異なる条件でパターンマッチングを行い、一致した箇所を"hit"で置き換える。
わざわざコピーを取る理由は、同じ文字列に対し連続でパターンマッチングをすると検索開始位置がずれてしまうからである。
最初のパターンマッチング(4行目)は"st(i|ru)ck"。
これは日常でも使われる書き方かもしれない。"|"は直前と直後のパターンの論理和を意味する。よって、このパターンは
stとckの間がiかruである部分、
すなわちstickまたはstruckのみにマッチする。結果を見ると実際にそうなっている。
2番めのパターンは"st.ck"。パターン中の".(ドット)"は、"任意の1文字"を表わす。 つまり、stとckの間に何か1文字入っている部分にマッチする。 今回はstickおよびstuckであった。
さて、3番めであるが、今回のパターンは"st.+ck"である。
"."は任意の一文字で、それに続く"+"は「直前のパターンの1回以上の繰り返し」を意味する。
従ってパターンは「stとckの間に任意の文字が1文字以上」を表わす。
これを踏まえると、結果は"hit hit hit stmach"となっていて欲しい所であるが、そうはなっていない。
実は、Perlのパターンマッチはデフォルトで最長マッチを行うようになっている。
最長マッチとは、見付けたパターンのうち最も長い物にマッチングさせることである。こう書いてもよく分からないと思うが、
"stick stuck struck stmach"
と言う風に、"stick stuck struck"をひとまとまりに考えてしまう、ということである。
これを踏まえて、4番めのパターンには、最短マッチを行わせる為、"+"の直後に"?"を付け加えている。 "+"のような、"あるパターンの繰り返し"を表わすものを量化子と言うが、量化子の直後に"?"をつけることで、 その量化子に対し最短マッチを行うように指定できる。これにより、4番めの出力はちゃんと "hit hit hit stmach"となる。
ただし、"?"については注意が必要である。"?"はそれ自体量化子であり、「0回または1回の繰り返し」を表わす。
なお、今回用いたような記号(. や + など)自体をパターンに使いたい場合は、その直前に"\"(バックスラッシュ)を置くことでエスケープすることができる。
正規表現およびパターンマッチングについては、書籍ならびにより情報量・信頼性の高いウェブサイトを参照することを強くお薦めします。
accend->Perl->labnote->index page