「すぐ分かる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」カテゴリの記事
- 「すぐわかるPerl」 8.10 ディレクトリのリカーシブ処理(その2)(2009.02.24)
- 「すぐわかるPerl」 8.10 ディレクトリのリカーシブ処理(その1)(2009.02.23)
- 「すぐわかるPerl」 7.6 マッチした文字列と、その前後の文字列を扱う変数(2008.06.17)
- 「すぐわかるPerl」 8.9 コマンドの入出力に入出力を切り替える(2008.11.12)
- 「すぐわかるPerl」 8.8 標準入出力以外のファイルの制御(2008.10.08)









コメント