|
|
Perl正規表現の使い方 複数の選択肢から選択 |
H.Kamifuji . |
複数の選択肢を列挙し、いずれかの選択肢にマッチする正規表現について確認します。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 |
|
複数の文字列を選択肢として記述し、いずれか一つに一致する場合にマッチする正規表現を作成します。 具体的な例として「Friday」「Saturday」「Sunday」のいずれかにマッチする正規表現は次のように記述します。
/Friday|Saturday|Sunday/
選択肢となる文字列をメタ文字である縦棒(|)で区切り、並べて記述します。3つ以上の選択肢がある場合は縦棒(|)をさらに追加し続けて記述して下さい。選択肢として記述された複数の文字列を左から順にマッチするかどうかをチェックされます。 また複数の選択肢を記述する時に、他の文字列などと組み合わせて使う場合を考えてみます。
/Today is Friday|Saturday|Sunday/
上記では「Today id Friday」「Today id Saturday」「Today id Sunday」のいずれかにマッチする正規表現を記述しようとしましたが、実際には「Today id Friday」「Saturday」「Sunday」のいずれかにマッチする正規表現となってしまいます。どこからどこまでが選択肢なのか分からないためです。 選択肢を他の部分と区別するためには、選択肢全体を括弧()で囲みます。
/Today is (Friday|Saturday|Sunday)/
これで「Today id Friday」「Today id Saturday」「Today id Sunday」のいずれかにマッチする正規表現となりました。 では簡単なプログラムで確認して見ます。 test1-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 複数の選択肢から一つ(|) use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「Today is (Friday|Saturday|Sunday)」にマッチするかどうか\n\n"; &check("Today is Friday"); &check("Today is Sunday"); &check("Today is Thursday"); &check("Tomorrow is Sunday"); &check("Saturday"); sub check{ my ($str) = @_; if ($str =~ /Today is (Friday|Saturday|Sunday)/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test1-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Select]$ perl test1-1_u.pl | nkf -w 「Today is (Friday|Saturday|Sunday)」にマッチするかどうか ○:Today is Friday ○:Today is Sunday ×:Today is Thursday ×:Tomorrow is Sunday ×:Saturday [xxxxxxxx@dddddddddd Select]$ |
メタ文字の「*」や「+」は選択肢全体に対しても適用することができます。よって、選択肢のいずれかが繰り返し現れる正規表現を定義することが可能です。(繰り返しに関しては「任意の文字と繰り返し(量指定子)」を参照して下さい)。 具体的な例で考えてみます。 /code (00|11)XX/上記の場合は「code 00XX」と「code 11XX」の2つの文字列のいずれかに一致する場合にマッチします。これに1回以上繰り返しが行われる場合にマッチするメタ文字「+」を付け加えてみます。
/code (00|11)+XX/
今度の場合、選択肢「(00|11)」に対してメタ文字の「+」が有効となりますので、「00」又は「11」のいずれかの文字列が1回以上繰り返されている場合にマッチすることになります。 例えば次のような文字列がマッチします。 code 00XX code 11XX code 0011XX code 11001111XXこのように選択肢と繰り返しを組み合わせることで、同じ選択肢が繰り返されるだけではなく、複数の選択肢のどれかが繰り返し現れる場合にマッチする正規表現を記述することが出来ます。 では簡単なプログラムで確認して見ます。 test2-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 選択肢全体を繰り返す use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「no(0|1|2)+ is」にマッチするかどうか\n\n"; &check("no0 is xxx"); &check("no2 is yyy"); &check("no11 is zzz"); &check("no021 is xxx"); &check("no03 is yyy"); &check("nois zzz"); sub check{ my ($str) = @_; if ($str =~ /no(0|1|2)+ is/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test2-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Select]$ perl test2-1_u.pl | nkf -w 「no(0|1|2)+ is」にマッチするかどうか ○:no0 is xxx ○:no2 is yyy ○:no11 is zzz ○:no021 is xxx ×:no03 is yyy ×:nois zzz [xxxxxxxx@dddddddddd Select]$ |
ここまでは固定の文字列を選択肢として記述してきましたが、文字列だけではなく「.」や「+」などのメタ文字を組み合わせて選択肢を記述することも出来ます。 具体的な例で考えてみます。 /(add_.+_|delete_.+_)/上記の場合は「add_.+_」と「delete_.+_」のいずれかに一致する場合にマッチします。 「add_.+_」の中の「.+」は任意の一文字である「.」が1回以上繰り返されるということなりますので、「add_」で始まり「_」で終わる文字列全てにマッチします。同じように「delete_.+_」は「delete_」で始まり「_」で終わる文字列全てにマッチします。 マッチするもの: add_display_ delete_prev_code_このように一つ一つの選択肢についても、単なる文字列だけではなくメタ文字などを組み合わせて記述することが可能です。 では簡単なプログラムで確認して見ます。 test3-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 選択肢に他のメタ文字を使用 use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「(add_.+_|delete_.+_)」にマッチするかどうか\n\n"; &check("add_panel_"); &check("delete_screen_margin_"); &check("add_control"); &check("delete__"); sub check{ my ($str) = @_; if ($str =~ /(add_.+_|delete_.+_)/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test3-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Select]$ perl test3-1_u.pl | nkf -w 「(add_.+_|delete_.+_)」にマッチするかどうか ○:add_panel_ ○:delete_screen_margin_ ×:add_control ×:delete__ [xxxxxxxx@dddddddddd Select]$ |
|