|
|
Perl正規表現の使い方 いずれかの文字に一致(文字クラス) |
H.Kamifuji . |
複数の文字を並べて記述し、どれか一つにマッチする正規表現について確認します。選択の場合と異なりマッチする対象が1文字ですが、連続した文字の集まりを簡潔に記述する方法が用意されています。 当ページでは、Linux CentOS7 の Gnome で動作テストしています。 |
|
マッチさせたい文字を全て列挙し、いずれか一つの文字にマッチする正規表現を作成します。 具体的な例として「A」「B」「C」のいずれかにマッチする正規表現は次のように記述します。
/[ABC]/
マッチさせたい文字を並べて記述し、全体をブラケット([])(角括弧とも言う)で囲います。この角括弧で囲まれた中に対象の文字を列挙したものを文字クラスと呼びます。 一文字だけのマッチですので単独で使用することはあまりなく、次のように他の文字などと組み合わせて使用します。 /199[6789]/上記では「1996」「1997」「1998」「1999」のいずれかにマッチします。 またこれは選択を使って次のように記述した場合と同じです。 /199[6789]/選択の場合は選択肢の間に縦棒(|)が必要ですが文字クラスの場合には文字と文字の間に区切りは不用です。その代わり選択の場合は複数の文字を組み合わせて選択肢に出来ますが、文字クラスではマッチさせる候補は一文字単位でしか指定できません。 なお文字クラスの中で記述する文字の順番は関係ありません。「[6789]」でも「[9786]」でも同じ結果となります。 では簡単なプログラムで確認して見ます。 test1-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 列挙した文字の一つ use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「199[6789]」にマッチするかどうか\n\n"; &check("199"); &check("1995"); &check("1996"); &check("1997"); &check("1998"); &check("1999"); &check("2000"); sub check{ my ($str) = @_; if ($str =~ /199[6789]/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test1-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Character]$ perl test1-1_u.pl | nkf -w 「199[6789]」にマッチするかどうか ×:199 ×:1995 ○:1996 ○:1997 ○:1998 ○:1999 ×:2000 [xxxxxxxx@dddddddddd Character]$ |
文字クラスを使用する場合、マッチさせたい文字を全て列挙します。列挙する文字ばバラバラの場合は一つ一つ記述するしかありませんが、例えば数字の「0から9」や文字の「aからz」などのように連続した文字を指定したい場合があります。このような場合にはメタ文字のハイフン(-)を使い範囲指定の形式で記述できます。 例として「0から9」までの文字を文字クラスの中で指定する場合には次のように記述できます。 /[0-9]/ブラケット([])の中でハイフン(-)を使用した場合だけハイフンはメタ文字としての意味を持ち、ハイフンの左側から右側までの連続した文字を記述した場合と同じです。よって上記は次のように記述した場合と同じです。 /[0123456789]/アルファベットの「aからz」までを全て文字クラスの中で指定する場合は次のどちらの記述方法でも同じ結果となります。 /[a-z]/ /[abcdefghijklmnopqrstuvwxyz]/同様にアルファベットの「AからZ」までを全て文字クラスの中で指定する場合は次のどちらの記述方法でも同じ結果となります。 /[A-Z]/ /[ABCDEFGHIJKLMNOPQRSTUVWXYZ]/今回は「0から9」や「aからz」などの先頭から最後までの場合で確認しましたが、「3から7」とか「dからm」などのような場合でも同じ記述方法で指定できます。(例えば/[3-7]/など)。 また範囲での指定に加えて他の文字を追加して指定することも可能です。 /[c-gxyz]/上記の場合は「cからg」までの全ての文字と「x」「y」「z」の3つの文字のいずれか一つにマッチします。 範囲の複数指定範囲は複数記述することが出来ます。例として「0から9」「aからz」「AからZ」を全て指定するには次のように記述します。/[0-9a-zA-Z]/範囲を記述する順番も関係ありませんので、[A-Z0-9a-z]のように記述しても同じです。 では簡単なプログラムで確認して見ます。 test2-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 連続した文字の指定方法 use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「200[0-9xX]」にマッチするかどうか\n\n"; &check("200"); &check("2001"); &check("2005"); &check("2010"); &check("200x"); &check("200X"); &check("200z"); sub check{ my ($str) = @_; if ($str =~ /200[0-9xX]/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test2-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Character]$ perl test2-1_u.pl | nkf -w 「200[0-9xX]」にマッチするかどうか ×:200 ○:2001 ○:2005 ×:2010 ○:200x ○:200X ×:200z [xxxxxxxx@dddddddddd Character]$ |
文字クラスはマッチする文字を全て列挙しますが、列挙した文字以外の場合にマッチさせることも可能です。このような場合にはメタ文字の「^」を使います。 例として「0から9」までの文字以外の文字にマッチさせたい場合には次のように記述できます。
/[^0-9]/
文字クラスを定義するブラケット([])の中で、「[」の直後に「^」が記述された場合にそれ以降に列挙された文字を否定する役割を持ちます。もしも「[」の直後以外に記述された場合は単なる「^」と言う文字となります。/[0-9^ab]/上記の場合は「0から9」「^」「a」「b」のいずれかにマッチする文字クラスとなります。 否定が使用された場合は、それ以降に書かれた文字を全て否定することになります。 /[^a-zA-Z]/上記では「a-z」「A-Z」以外の文字にマッチします。 また「^」は文字列の先頭にマッチするメタ文字としても使用されていますが、文字クラスの[]の中で使用された場合だけは今回ご説明している否定を意味するメタ文字となりますので注意して下さい。 では簡単なプログラムで確認して見ます。 test3-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 文字クラスの否定 use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「200[^a-zA-Z]」にマッチするかどうか\n\n"; &check("200"); &check("2001"); &check("2005"); &check("2010"); &check("200x"); &check("200X"); &check("200#"); sub check{ my ($str) = @_; if ($str =~ /200[^a-zA-Z]/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test3-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Character]$ perl test3-1_u.pl | nkf -w 「200[^a-zA-Z]」にマッチするかどうか ×:200 ○:2001 ○:2005 ×:2010 ×:200x ×:200X ○:200# [xxxxxxxx@dddddddddd Character]$ |
文字クラスはブラケット([])内にマッチする文字を列挙しますが、[]内とそれ以外の場所でメタ文字の扱いが異なります。ここでは一つ一つ確認しておきます。 ハイフン(-)[]内でハイフン(-)を記述した場合は、ハイフン(-)の左側から右側までの連続した範囲を表すメタ文字となります。/[0-9P]/上記では「0,1,2,3,4,5,6,7,8,9,P」のいずれかの文字にマッチします。 []内でハイフン(-)を単なる文字の「-」として扱う場合には「\」を使ってエスケープします。 /[0\-9P]/上記では「0,-,9,P」のいずれかの文字にマッチします。 またハイフン(-)が[]内の先頭に記述されていた場合、ハイフンの左側の値が存在しませんので範囲として意味を持ちません。よってハイフン(-)が[]の先頭に記述されていた場合はエスケープ無しでも単なる文字の「-」となります。([]内では文字が記述された順序に意味を持ちませんので、ハイフン(-)を文字として含めたい場合は単に先頭に記述します)。 /[-09P]/上記では「0,-,9,P」のいずれかの文字にマッチします。 ハイフン(-)は[]以外の場所では特別な意味を持ちませんので単なる文字として扱われます。 /2000-200[1-3]/上記では[]内のハイフンは範囲を表すメタ文字ですが、パターンの真ん中あたりにあるハイフン(-)は単なる文字のハイフン(-)です。よって「2000-2001」「2000-2002」「2000-2003」にマッチします。 キャレット(^)[]内でキャレット(^)を先頭に記述した場合は、それ以降に列挙された文字を否定するメタ文字となります。/[^0-4abc]/上記では「0,1,2,3,4,a,b,c」以外のの文字にマッチします。 ただし[]内であっても先頭以外の場所に記述された場合は単なる文字の「^」として扱われます。 /[0-4^abc]/上記では「0,1,2,3,4,^,a,b,c」のいずれかの文字にマッチします。 キャレット(^)は[]以外の場所では文字列の先頭にマッチするメタ文字となります。(詳細は「文字列の先頭(^)」を参照して下さい)。 /^[^012]xx/上記では[]内のキャレット(^)は否定を表すメタ文字ですが、「[」の前にあるキャレット(^)はパターンが文字列の先頭にある場合だけマッチすることを表すメタ文字です。よって「0」「1」「2」以外の文字から始まり「xx」がその後に続き、文字列の先頭から記述されている場合だけマッチします。 「.」「*」「+」「?」「{」「}」「|」「[」文字クラス以外で使用される下記のメタ文字は文字クラス内では特別な意味を持ちませんので単なる文字として扱われます。/[.*+?(){}|]/上記では「.,*,+,?,(,),{,},|」のいずれかの文字にマッチします。 []内に「[」が含まれていた場合も単なる文字の「[」として扱われます。(ただし「]」は異なりますので注意して下さい)。 /[0[A]/上記では「0,[,A」のいずれかの文字にマッチします。 「]」「\」ブラケットの終わりの「]」が[]内に記述されていた場合、ブラケットがそこで終わってしまいます。/[0]A]/そこで「]」を[]内で記述する場合は「\」を使ってエスケープします。 /[0\]A]/また「\」記号も[]内では他の文字のエスケープや文字の集合を表す特別なショートカットとして使用されますので、単なる文字の「\」を[]内に記述する場合は「\」を使ってエスケープします。 /[0\\A]/ その他他にもいくつかありますので、随時このページは更新していきます。では簡単なプログラムで確認して見ます。 test4-1.pl サンプルプログラム下記のサンプルを実行してみよう。# 文字クラス内のメタ文字の扱い # use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「200[.*+?[(){}|\\]\\\\]」にマッチするかどうか\n\n"; &check("200."); &check("200*"); &check("200+"); &check("200?"); &check("200["); &check("200{"); &check("200}"); &check("200("); &check("200)"); &check("200|"); &check("200]"); &check("200\\"); sub check{ my ($str) = @_; if ($str =~ /200[.*+?[(){}|\]\\]/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test4-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Character]$ perl test4-1_u.pl | nkf -w 「200[.*+?[(){}|\]\\]」にマッチするかどうか ○:200. ○:200* ○:200+ ○:200? ○:200[ ○:200{ ○:200} ○:200( ○:200) ○:200| ○:200] ○:200\ [xxxxxxxx@dddddddddd Character]$ |
文字クラスは列挙した文字の一覧のどれかにマッチするものですが、頻繁に利用される文字クラスがあります。例えばいずれかの数字にマッチする「[0-9]」などは頻繁に利用されます。このようなよく使用される文字クラスを表す略記法が用意されています。 ここでは文字クラスの略記法について確認していきます。 数字を表す「\d」「\D」「\d」は数字を表す略記法です。文字クラスの「[0-9]」に該当します。/[0-9]/ /\d/ /[\d]/上記ではいずれも「0,1,2,3,4,5,6,7,8,9」のいずれかにマッチします。「\d」は文字クラスを表すブラケット[]の外側でも記述できますがブラケット内にも記述することが出来ます。 また「\D」は数字以外を表す略記法です。文字クラスの「[^0-9]」又は「[^\d]」に該当します。 /[^0-9]/ /[^\d]/ /\D/ /[\D]/上記ではいずれも「0,1,2,3,4,5,6,7,8,9」以外の文字のいずれかにマッチします。 「\d」を使い任意の桁数の数字にマッチさせる場合は次のように記述できます。 /\d+/※キャレット(^)はブラケット[]内に記述した場合だけ否定の意味を持ちますので「^\d」はまったく違う意味になりますので注意して下さい。 単語の構成文字を表す「\w」「\W」「\w」は単語を構成する文字の一つを表す略記法です。文字クラスの「[a-zA-Z0-9_]」に該当します。アルファベット、数字、アンダーバーのいずれかにマッチします。/[a-zA-Z0-9_]/ /\w/ /[\w]/上記ではいずれも「aからz」「AからZ」「0から9」「_」のいずれかにマッチします。「\w」は文字クラスを表すブラケット[]の外側でも記述できますがブラケット内にも記述することが出来ます。 また「\W」は単語を構成する文字以外を表す略記法です。文字クラスの「[^a-zA-Z0-9_]」又は「[^\w]」に該当します。 /[^a-zA-Z0-9_]/ /[^\w]/ /\W/ /[\W]/上記ではいずれも「aからz」「AからZ」「0から9」「_」以外の文字のいずれかにマッチします。 「\w」を使い任意の連続する単語を構成する文字にマッチさせる場合は次のように記述できます。 /\w+/ 空白文字を表す「\s」「\S」」は空白文字を表す文字の一つを表す略記法です。空白文字とは空白「 」の他に改行「\n」、復帰「\r」、改ページ「\f」、水平タブ「\t」です。文字クラスの「[ \n\r\f\t]」に該当します。br>/[ \n\r\f\t]/ /\s/ /[\s]/上記ではいずれも空白、改行、復帰、改ページ、水平タブ以外の文字のいずれかにマッチします。 「\s」を使い任意の連続する空白文字に文字にマッチさせる場合は次のように記述できます。 /\s+/では簡単なプログラムで確認して見ます。 test5-1.pl サンプルプログラム下記のサンプルを実行してみよう。# よく使用される文字クラスの略記 use strict; use warnings; use utf8; binmode STDIN, ':encoding(cp932)'; binmode STDOUT, ':encoding(cp932)'; binmode STDERR, ':encoding(cp932)'; print "「_\\w+_」にマッチするかどうか\n\n"; &check("_end_"); &check("_op2000_"); &check("_NO011nen_"); &check("_and"); &check("print_"); &check("_graph#you_"); &check("_color red_"); sub check{ my ($str) = @_; if ($str =~ /_\w+_/){ print "○:$str\n"; }else{ print "×:$str\n"; } }上記を「test5-1.pl」の名前で保存してから次のように実行して下さい。 ![]() Linux 環境での実行結果は、下記です。シフトJIS で出力されるので nkf -w で UTF-8 に変換しています。 [xxxxxxxx@dddddddddd Character]$ perl test5-1_u.pl | nkf -w 「_\w+_」にマッチするかどうか ○:_end_ ○:_op2000_ ○:_NO011nen_ ×:_and ×:print_ ×:_graph#you_ ×:_color red_ [xxxxxxxx@dddddddddd Character]$ |
|