Perl入門 ≫ LESSON15 正規表現
正規表現とは?
Perlの特徴の一つがコレ、正規表現でしょう。
まったくわからない人が見ればただの意味不明なものですが、慣れれば簡単ですし、正規表現自体は他の言語等でも使えますので、是非覚えて下さい。
では、実際にどういうモノかと言いますと・・・
例えば、perlではディレクトリに存在するファイルの一覧を取ることができます。
今、あるディレクトリにファイルが複数存在しているとして、その中から『ファイル名の最初が't'という文字で始まり、拡張子が'.txt'のファイル名の一覧を取得したい』時、
取得した全部のファイル名の中から、上の条件に当てはまるものだけ探せばいいのです。
その時、各ファイル名は
$filename =~ /^t.+\.txt$/;
というパターンに当てはめて、合っている・いない(マッチング)、を判定します。
このパターンについては徐々に説明します。
また、パターンに当てはめて判定する他に、指定したパターンから部分部分を抜き出すこともできます。
$filename =~ /^(t.+)\.txt$/;
これで特殊変数$1にファイル名の拡張子を取った部分が入ります。
パターンのお約束
●パターンは、基本的に
/パターン/
という形で表現します。パターンの前後を'/'で囲います。
●では、パターンに当てはめる変数をどうやって指定するかと言うと、次のようになります。
変数 =~ /パターン/
'=~'を使うと左辺に指定した変数をパターンに当てはめます。
変数を指定しないと、特殊変数$_に当てはめます。
●パターンに合っている・いないを判定するのに、最初から否定の形で表現することもできます。
if(変数 !~ /パターン/) { }
'!~'を使うと左辺に指定した変数が、パターンに当てはまらなければ条件文を実行します。
'=~'と'unless'を使うのと同じ事ですが。
●パターンには、オプションを付けることもできます。その時、
/パターン/オプション
という形で指定します。
部分パターンの参照
指定したパターンから一部分を抜き出して参照することができます。
/(パターン1)パターン2(パターン3)../
ってな具合に取り出したい部分のパターンを括弧で括ります。 すると、マッチング終了後、最初の括弧から$1,$2,$3..という特殊変数で参照できます。
#適当な配列を用意
my $v = "abcdefghijklmn";
#^とは文字列の先頭を表す。.+とは、1文字以上の文字列のパターン。
つまり、文字列の最初から'def'までの文字列と、その次の文字から'l'が出てくるまでの文字列を取り出します。
$v =~ /^(.+)def(.+)l/;
print "$1 $2";
結果
abc ghijk
パターン
では、実際そのパターンというのは次のようなものです。
●そのままの文字・数字
素直に固定の文字や数字をパターンに指定できます。
#適当な配列を用意
my @v = ('abc','abb','cef','ad3','eab','33r');
foreach my $tmp (@v) {
#文字列'ab'を含む要素を出力
if($tmp =~ /ab/) { print "$tmp\n"; }
}
結果
abc
abb
eab
#適当な配列を用意
my @v = ('12c','e3b','45f','ad3','eab','33r');
foreach my $tmp (@v) {
#数字3を含む要素を出力
if($tmp =~ /3/) { print "$tmp\n"; }
}
結果
e3b
ad3
33r
●特殊文字
パターンの中には特殊文字も指定できます。
特殊文字は、「スカラー:文字」の所にある『エスケープシーケンス一覧』が主なものです。
また、特殊文字を固定の文字としてパターンの中で指定したい場合、文字をエスケープする必要があります。
+ ? . * ^ $ ( ) [ ] { } | /
この各文字はパターンの中で特別な意味を持って使われてしまいますので、
そのままの文字の意味で使いたい場合は、各文字の前に'\'を付けてエスケープします。
#\tはタブを表す
my @v = ("ab\tc","b\tcd","abc");
foreach my $tmp (@v) {
#"\t"(タブ)を含む要素を出力
if($tmp =~ /\t/) { print "$tmp\n"; }
}
ab c
b cd
my $v = 'test/aaa.txt';
#'/'をマッチさせる。下記の様に'/'をエスケープしないとエラーになる。
if($v =~ /\//) {
print $v;
}
test/aaa.txt
●その他の特殊文字
他にも便利な特殊文字が指定できます。
\w | 英数字および_とマッチする。\Wは\w以外の文字。 |
---|---|
\s | 空白とマッチする。\Sは空白以外。 |
\d | 数字とマッチする。\Dは数字以外。 |
\A | 文字列の先頭とマッチする。 |
\Z | 文字列の末尾か、最後の改行文字の前とマッチする。 |
\z | 文字列の物理的な末尾とマッチする。 |
\b | 単語境界とマッチする。\Bは境界以外とマッチする。 |
\G | オプションgが指定されている時に、直前のマッチが終了した一にマッチする。 |
\p{属性} | 名前による属性指定に従ってマッチを行う。\P{属性}はその属性以外にマッチする。 次で詳しく説明する。 |
\X | Unicodeの結合文字列にマッチする。 |
\C | 8ビットバイトにマッチする。 |
\1.....\9 | 部分パターンを参照。置換関数中で使うが、$1,$2..でも同様。 |
my @v = (123, 'd3', 'abc');
foreach my $tmp (@v) {
#"\d"(数字)を含む要素を出力
if($tmp =~ /\d/) { print "$tmp\n"; }
}
123
d3
●属性指定
上の文字クラスと同様、属性指定でマッチングできます。
\p{IsAlpha} [:alpha:] | アルファベット文字とマッチする。 |
---|---|
\p{IsDigit} [:digit:] | 数字とマッチする。(\dと同じ) |
\p{IsAlnum} [:alnum:] | アルファベットか数字とマッチする。 |
\p{IsASCII} [:ascii:] | ASCII文字とマッチする。 |
\p{IsCntrl} [:cntrl:] | 制御文字とマッチする。 |
\p{IsPunct} [:punct:] | 記号文字とマッチする。 |
\p{IsGraph} [:graph:] | 英数字、あるいは記号文字とマッチする。 |
\p{IsSpace} [:space:] | 空白文字とマッチする。(\sと同じ) |
\p{IsWord} [:word:] | 単語構成文字とマッチする。(\wと同じ) |
\p{IsPrint} [:print:] | 英数字・記号文字・あるいは空白とマッチする。 |
\p{IsLower} [:lower:] | 英小文字とマッチする。 |
\p{IsUpper} [:upper:] | 英大文字とマッチする。 |
\p{IsXDigit} [:xdigit:] | 16進数用数字とマッチする。 |
my @v = (123, 'd3', 'abc');
foreach my $tmp (@v) {
#[:alpha:](アルファベット)だけから構成される要素を出力
if($tmp =~ /[:alpha:]/) { print "$tmp\n"; }
}
abc
下の段に書いた[:クラス名:]の形式はPOSIXクラスと言い、同じ意味で使えます。
この否定は^を使って[:^クラス名:]と書きます。
●その他のパターン
その他・・・と言いますが実はよく使います。
. | 任意の文字とマッチする。 |
---|---|
(パターン) | パターンのグループ化 |
^ | 対象文字列の先頭とマッチする。 |
$ | 行の末尾か最後の改行文字の直前とマッチする。 |
[...] | マッチする文字クラスを示す。(一文字) [^...]は指定した文字以外の集合を意味する。 ex)[\s\d] 数字か空白を表す。 a-zでアルファベットのaからzを、A-ZでAからZを表す。数字も同様。 |
...|...|... | 左から右に向かって選択肢のマッチを行い、成功した時点で中止する。 |
●出現回数表示
パターンになる要素の連続出現回数を指定できます。
パターンに続けて次の記述方法で表現します。
+ | 直前のパターン要素と一回以上マッチする。 |
---|---|
* | 0回以上マッチする。 |
? | 0または1回だけマッチする。 |
{n,m} | n回以上、m回以下マッチする。 {n}はn回マッチする。 |
my $v = "abc123def4gh";
$v =~ /^([^\d]+)\d{3}(.*)$/;
#先頭から次の数字まで、次のアルファベットから語尾までにマッチする。
print "\'$1\' \'$2\'";
'abc' 'def4gh'
オプション
パターンには様々なオプションを指定することができます。指定したオプションによって、
マッチング結果は異なる場合があります。
パターンになる要素の連続出現回数を指定できます。
パターンに続けて次の記述方法で表現します。
c | (gと共に使い)継続検索を行う。 |
---|---|
g | 可能なだけマッチを行う。 例えば、普通に$v =~ /abc/;とすると、指定した文字列の中で最初に'abc'という文字列が現れた時点でマッチングは終了されてしまう。 |
i | 大文字・小文字を区別しない。 |
o | 1回だけ変数展開を行う。 |
m | 文字列を複数行として行う。^と$は文字列中の改行文字とマッチする。 |
s | 文字列を単独行として扱う。.は文字列中の改行文字とマッチする。 |
x | 空白とコメントを許可する。 |
マッチ結果後の特殊変数
マッチングが成功すると、上でやった「部分パターンの参照」も含めて他にも色々参照できる特殊変数があります。
c | (gと共に使い)継続検索を行う。 |
---|---|
g | 可能なだけマッチを行う。 例えば、普通に$v =~ /abc/;とすると、指定した文字列の中で最初に'abc'という文字列が現れた時点でマッチングは終了されてしまう。 |
$& | マッチした文字列。 |
$` | マッチした部分より前にある文字列。 |
$' | マッチした部分より後ろにある文字列。 |
$1,$2.. | 部分パターンにマッチした文字列。 |
$+ | マッチした最後の部分文字列。 |
@- | 全体マッチと部分マッチの開始オフセットのリスト。 |
@+ | 対応する終了オフセットのリスト。 |
my $v = "abc123def4gh";
$v =~ /\d{3}/;
print "\'$`\' \'$'\'";
'abc' 'def4gh'
これらの値は、次のマッチングを行うまで特殊変数に保存されます。
split
「リスト関数」の所で出てきたsplit関数のパターンは、この正規表現を利用します。
my $v = "abc123def4gh";
my @k = split(/\d+/, $v);
print "@k";
abc def gh