Akihiro's Programmer Blog

Technology Notes for Personal

「初めてのPerl」 第八章 - 2

第八章の続きから。

第八章 正規表現によるマッチ

内容

用語集

用語 説明
マッチ(キャプチャ)変数 パターンマッチする際に得られる文字列を格納している変数

Point

ある文字列から一部分の文字列を抜き出したい
$_ = "abc";
# ()で囲んだ部分を$1で取り出せる()
if (/a(.)c/) {
    print "$1";          # => b
}

# 2つ以上ある場合$1,$2,$3...と順番に取り出せる
if (m/(.)(.)(.)/) {
    print "$1,$2,$3";    # => a,b,c
}

# ちなみにマッチ変数の有効期限は次のマッチが成功するまで
# だからパターンマッチはifやwhileの条件式として使われることが多い
()をグルーピングだけに用いたい
$_ = "abc";
# ()で囲むとマッチ変数に値が入る
if (/(.)b(.)/) {
    print "$1";    # => a
}

# でも(?:)とするとマッチ変数に値が入らない
if (/(?:.)b(.)/) {
    print "$1";    # => c
}
キャプチャに分かりやすく名前をラベルを付けたい
$_ = "abc";
# $1,$2とかじゃ分かりにくい場合
if (/(.)b(.)/) {
    print "$1,$2";                    # => a,c
}

# (?<ラベル名>)でマッチ変数にラベルが付けられる
if (/(?<label1>.)b(?<label2>.)/) {
    print "$+{label1},$+{label2}";    # => a,c
}
マッチした部分とそうでない部分を取得したい
$_ = "abc";
# $` :マッチした部分より前
# $& :マッチした部分
# $' :マッチした部分より後
if (/(.)(.)(.)/) {
    print "$`,$&,$'";                               # => a,b,c
}

# perl 5.10以降なら/p修飾子を付けるとこんな感じで出来る
if (/(.)(.)(.)/p) {
    print "${^PREMATCH},${^MATCH}${^POSTMATCH}";    # => a,b,c
}

# ちなみに前者の方法だと他の全ての正規表現が少し遅くなる...らしい
# 数ミリ秒の話
汎用な量指定子を使いたい
$_ = "aaaaa";
# *,+,?とかよりもっと汎用的な量指定子が使いたい場合は
if (/a{1,5}/) {
    print "OK!";    # 1から5回 aが繰り返されたらマッチする
}

if (/a{3,}/) {
    print "OK!";    # 3回以上 aが繰り返されたらマッチする
}

if (/a{5}/) {
    print "OK!";    # 5回丁度 aが繰り返されたらマッチする
}
次回は

次回は第九章を予定。