« 「すぐ分かるPerl」6.5 行番号をうってみよう | トップページ | 「すぐ分かるPerl」6.7 その他の正規表現 »

2008年5月 8日 (木)

「すぐ分かるPerl」6.6 正規表現による検索

正規表現について。
これは時々業務でつかいます。ログの中から該当する文字列見つけるのに使ったり。

# num -- goodの文字列を含む行を出力
while (<STDIN>) {
if(/Good/){
print;
}
}

出力結果

perl perltest.pl < greetings.txt
Good Morning
Good bye

ここでの「/文字列/」をマッチ演算子という。
デフォルトの作用対象が$_

ファイル(people.txt)を作成する。

Michal Jackson
Janet Jackson
Joe Jackson
Joni Mitchel
Jackson 5
Michal Johnson
Jon Anderson
Sade
Hiroko Shimabukuro
Eriko Imai
Takako Uehara
Hitoe Arakaki
John Paul Jones
14 carats soul
Prince
UK
US3

時代を感じるラインナップだなぁ・・・
苗字がJacksonの人を検索する場合。

/Jackson/

# num -- Jacksonの文字列を含む行を出力
while (<STDIN>) {
if(/Jackson/){
print;
}
}

出力結果

perl perltest.pl < people.txt
Michal Jackson
Janet Jackson
Joe Jackson
Jackson 5

グループ名のJackson5まで一致したと判断されるため、末尾に一致する場合の未表示とする。

# num -- Jacksonの文字列を含む行を出力
while (<STDIN>) {
if(/Jackson$/){
print;
}
}

うーん、これがうちの環境ではなぜかうまく出ない・・・

本来であれば

Michal Jackson
Janet Jackson
Joe Jackson

という結果が出るのだけど、何も結果が表示されない。
$を追加するだけだから、間違いないはずなのになぁ。

とりあえず、先に進む。

先頭にマッチングさせる場合には^を付与する。
Jから始まるものを書き出す場合

# num -- Jacksonの文字列を含む行を出力
while (<STDIN>) {
if(/^J/){
print;
}
}

これは出た。

perl perltest.pl < people.txt
Janet Jackson
Joe Jackson
Joni Mitchel
Jackson 5
Jon Anderson
John Paul Jones

数字を含むものの場合、文字クラスをつかう。

/[0123456789]/

複数の文字のどれかにマッチするパターン

連続した文字コードの場合には範囲指定も可能。

/[0-9]/

これで0から9までの文字コード1文字にマッチする。

perl perltest.pl < people.txt
Jackson 5
14 carats soul
US3

数字を含まない、場合にはクラスの先頭に^を付与する
/[^0-9]/
ただし、これは「数字以外の文字をふくむ」場合にマッチすることになり、数字以外の普通の文字が含まれればマッチしてしまう。

文字列の最初から最後まで数字以外、という場合にはこのようになる。

/^[^0-9]+$/

最初の^は先頭をあらわし、次の^は[]つまり文字クラスの中なので否定をあらわし、+は1回以上の繰り返し、$は末尾。

# num -- Jacksonの文字列を含む行を出力
while (<STDIN>) {
if(/^[^0-9]+$/){
print;
}
}

出力結果

perl perltest.pl < people.txt
Michal Jackson
Janet Jackson
Joe Jackson
Joni Mitchel
Michal Johnson
Jon Anderson
Sade
Hiroko Shimabukuro
Eriko Imai
Takako Uehara
Hitoe Arakaki
John Paul Jones
Prince
UK

これはうまくいった!
で、さらにJから始まるという条件を付与する。

# num -- Jacksonの文字列を含む行を出力
while (<STDIN>) {
if(/^J[^0-9]+$/){
print;
}
}

出力結果

perl perltest.pl < people.txt
Janet Jackson
Joe Jackson
Joni Mitchel
Jon Anderson
John Paul Jones

おー。すばらしい。

perlの場合には数字以外の一文字というのはあらかじめ組み込まれている。

\Dと書くと、[^0-9]と同じ意味になる。つまり

/^J\D+$/

と書いても同じ意味になる。

なお、数字一文字は\dであり、これは

/[0-9]/

と同じ意味合いを持つ。

●一語の名前を検索

US3やPrinceなど一語で終わるものをマッチさせるには、スペース以外で終始すればいい。スペース以外を示すには\Sという文字クラスがある。

/~\S+$

\Sと\sは分かるのだけど、このスペース以外で終止するという意味が分からなかった。

●3語の名前を検索

これは「スペース以外」+「スペース」+「スペース以外」+「スペース」+「スペース以外」の組み合わせで実現させる。

/^\S+\s+\S+\s+\S+$/

とあるのだが、なぜかうまくいかないので

/^\S+\s+\S+\s+\S/

でok。
ウチの環境は正規表現の末尾の扱いが違うのかなぁ。まぁいいや。

|

« 「すぐ分かるPerl」6.5 行番号をうってみよう | トップページ | 「すぐ分かるPerl」6.7 その他の正規表現 »

Perl」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/214806/41063098

この記事へのトラックバック一覧です: 「すぐ分かるPerl」6.6 正規表現による検索:

« 「すぐ分かるPerl」6.5 行番号をうってみよう | トップページ | 「すぐ分かるPerl」6.7 その他の正規表現 »