好奇心旺盛な出不精。 RSSフィード

2009-03-03

勉強する〜第7章:正規表現の基本〜

とうとうきました正規表現

第7章

正規表現(pattern)とは

文字列に対してmatchさせられるテンプレートのこと。

「マッチする」か「マッチしない」かの二択のみ。

Unixgrepコマンドみたく使える。


パターンをマッチさせる書き方

//で指定する。

$_ = "yabba dabba doo";
if (/abba/) {
  print "It matched!\n";
}

メタキャラクタ(特殊文字)

ドット(.)はワイルドカード文字。

改行文字("\n")を除いた、あらゆる文字1個にマッチする。

/bet.y/ # "betty"、"besty"、"bet=y"、"bet.y"などにマッチする("bety"にはマッチしない!)

単純な量指定子

アスタリスク(*)は直前のものに0回以上マッチする。

「直前のものが星の数ほど現れてもいい。たとえ0回でもいい」

/fred\t*barney/ # fredとbarneyの間にタブが何個あってもマッチするし、"fredbarney"にもマッチする
/fred.*barney/ # fredとbarneyの間にどんな「ガラクタ」があってもマッチする

プラス記号(+)は直前に置かれたものに1回以上マッチする。

「直前のものに加えて同じものが何個あってもいい」

/fred +barnney/ # fredとbarneyの間に(1個以上の)スペースが置かれている場合にマッチする("fredbarney"にはマッチしない)

クエスチョン記号(?)は直前のものが省略可能である。

「直前のものがある?それともない?」

/bamm-?bamm/ # "bamm-bamm"か"bammbamm"のどちらかにマッチする

ちょっとしたやり方や注意として。

/fred+/ # "fredddddddddddddd"にマッチする
/(fred)+/ # "fredfredfred"にマッチする
/(fred)*/ # "hello, world"や空白文字にマッチする

選択肢

縦棒(|)は、その左側か右側のどちらか一方にマッチすることを表わす。つまりor。

/fred|barney|betty/ " "fred"、"barney"、"betty"のどれかを含む文字列にマッチする
/fred( |\t)+barney/ # "fred  \t\t\t\t\t   \t \t  \t \t\t barney"にマッチする

パターンをテストするプログラム

while (<>) {
  chomp;
  if (/ここにパターンを置く/) {
    print "Matched: |$`<$&>$'|\n"; # 9章で解説してくれるんだってさ...
  } else {
    print "No match.\n";
  }
}

実際にマッチした部分は、<>に囲んで表示されるんだって!


第7章の練習問題

7-1.fredを含む全ての文字列にマッチするパターンを作成しろ。
/fred/

7-2.少なくとも1個のaの後ろに、任意個(0個も含む)のbが続くような部分を持った、全ての文字列にマッチするパターンを作成しろ。
/a+b*/

7-3.任意個(0個も含む)の逆スラッシュの後ろに、任意個のアスタリスクが続くような部分を持った、全ての文字列にマッチするパターンを作成しろ。
/\\*\**/

7-4.wilmaを含む全ての入力行を表示するプログラムを書け(それ以外の行は表示せずスキップする)。
while (<>) {
  if (/(w|W)ilma/) {
    print;
  }
}

7-5.wilmaとfredの両方が含まれている行を表示するプログラムを書け。

正規表現には、orはあるけどandは存在しないのよ〜

while (<>) {
  if (/(wilma)+/) {
    if (/(fred)+/) {
      print;
    }
  }
}

これを考えてた。だって正規表現の章でしょ?w

while (<>) {
  if (/wilma.*fred|fred.*wilma/) {
      print;
  }
}

総括

まだ導入編程度の正規表現の深さなんだろうな。

でも正規表現たのしす。