┌───────┐
│perl超入門(3) │
│ 2002/10/27 │
└───────┘
[▲Perl Home▲]
●パターンマッチ
◆マッチ演算子
・マッチ演算子「/指定文字列/」 によりデータが指定文字列を含むか否かをチェック。
・マッチ対象にはメタ文字(\n, \a, \t)も含まれる。
・特別な(マッチ/正規表現上特別な意味を持つ)文字にはエスケープ表記(\記号を付
ける)を適用する。(例は示さない)
. : \.
\ : \\
* : \*
? : \?
| : \|
+ : \+
^ : \^
・機種により\記号はバックスラッシュになる。
┌─────────────────────────────────────┐
while (<>) {
if (/abc/) {
print "○ ", $_;
} else {
print "× ", $_;
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
[data.txt]
┌───────┐
│abc:001 │
│ABC:002 │
│abcdefg:004 │
│ABCDEFG:005 │
│012abcdefg:006│
│012ABCDEFG:007│
└───────┘
C:> jperl test.pl data.txt
○ abc:001
× ABC:002
○ abcdefg:004
× ABCDEFG:005
○ 012abcdefg:006
× 012ABCDEFG:007
└─────────────────────────────────────┘
・大文字と小文字を区別させないオプション「/指定文字列/i」。
┌─────────────────────────────────────┐
while (<>) {
if (/abc/i) {
print "○ ", $_;
} else {
print "× ", $_;
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
[data.txt] ← 前の例と同じ
C:> jperl test.pl data.txt
○ abc:001
○ ABC:002
○ abcdefg:004
○ ABCDEFG:005
○ 012abcdefg:006
○ 012ABCDEFG:007
└─────────────────────────────────────┘
◆パターン結合演算子
・マッチ対象を変数と結び付けるには、パターン結合演算子「=~」を使用。
┌─────────────────────────────────────┐
@datas = ( 'abc:001',
'ABC:002',
'abcdefg:004',
'ABCDEFG:005',
'012abcdefg:006',
'012ABCDEFG:007' );
foreach $tmp (@datas) {
if ($tmp =~ /abc/) {
print "○ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abc:001
× ABC:002
○ abcdefg:004
× ABCDEFG:005
○ 012abcdefg:006
× 012ABCDEFG:007
└─────────────────────────────────────┘
◆アンマッチ
・マッチしないことはパターン結合演算子の一つである「!~」で表す。
┌─────────────────────────────────────┐
@datas = ( 'abc:001',
'ABC:002',
'abcdefg:004',
'ABCDEFG:005',
'012abcdefg:006',
'012ABCDEFG:007' );
foreach $tmp (@datas) {
if ($tmp !~ /abc/) {
print "○ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
× abc:001
○ ABC:002
× abcdefg:004
○ ABCDEFG:005
× 012abcdefg:006
○ 012ABCDEFG:007
└─────────────────────────────────────┘
・否定は結合演算子で表すので、$_の省略に対しては否定表現が無い。この場合は省
略しないで記述する。
if ($_ !~ /abc/) {
:
}
◆マッチ演算子の文字変更
・マッチ対象文字列に「/」を含んでいる場合、マッチ演算子の文字を変更する。
mマッチ演算子文字 → m#/abc#
m%/abc% 等々...
┌─────────────────────────────────────┐
@datas = ( '/abc:001', #検索対象1
'ABC:002',
'abcdefg:004',
'ABCDEFG:005',
'012/abcdefg:006', #検索対象2
'012ABCDEFG:007' );
foreach $tmp (@datas) {
if ($tmp =~ m#/abc#) {
print "○ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ /abc:001
× ABC:002
× abcdefg:004
× ABCDEFG:005
○ 012/abcdefg:006
× 012ABCDEFG:007
└─────────────────────────────────────┘
●正規表現
◆行頭/行末
・文字列中に意味のあるメタ文字を適用することが出来る:正規表現
・行頭/行末の表現
^ : 行頭
$ : 行末
\Z : \n行末 ← chop()されていない変数等に適用
\n(改行)をエスケープする
┌─────────────────────────────────────┐
while (<>) {
if (/^abc/) {
print "○ ", $_;
} else if (/6\Z/){
print "△ ", $_;
} else {
print "× ", $_;
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
[data.txt]
┌───────┐
│abc:001 │
│ABC:002 │
│abcdefg:004 │
│ABCDEFG:005 │
│012abcdefg:006│
│012ABCDEFG:007│
└───────┘
C:> jperl test.pl data.txt
○ abc:001
× ABC:002
○ abcdefg:004
× ABCDEFG:005
△ 012abcdefg:006
× 012ABCDEFG:007
└─────────────────────────────────────┘
◆数字/数字以外 : (半角)
\d : 数字1文字
\D : 数字以外1文字
┌─────────────────────────────────────┐
@datas = ( 'abc:001',
'ABC:002',
'Gabcdefg:004',
'SABCDEFG:005',
'012abcdefg:006',
'012ABCDEFG:007' );
foreach $tmp (@datas) {
if ($tmp =~ /\dabc/) {
print "○ ", $tmp, "\n";
} elsif ($tmp =~ /\Dabc/) {
print "△ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
× abc:001
× ABC:002
△ Gabcdefg:004
× SABCDEFG:005
○ 012abcdefg:006
× 012ABCDEFG:007
└─────────────────────────────────────┘
◆英数字/英数字以外 : (半角)
\w : 英数字1文字
\W : 英数字以外1文字 (@, :, ; 等の記号とマッチ)
(注)_(アンダーバー)は英文字扱いとなる
┌─────────────────────────────────────┐
@datas = ( 'abc001',
'ABC002',
'Gabc:defg003',
'Gabc_defg004',
'SGABCDEFG005' );
foreach $tmp (@datas) {
if ($tmp =~ /abc\w/) {
print "○ ", $tmp, "\n";
} elsif ($tmp =~ /abc\W/) {
print "△ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abc001
× ABC002
△ Gabc:defg003
○ Gabc_defg004
× SGABCDEFG005
└─────────────────────────────────────┘
◆空白/空白以外 : (半角)
\s : 空白1文字
\S : 空白以外1文字
┌─────────────────────────────────────┐
@datas = ( 'abc 001',
'abc_002',
'defg 003',
'defg004' );
foreach $tmp (@datas) {
if ($tmp =~ /abc\s/) {
print "○ ", $tmp, "\n";
} elsif ($tmp =~ /\s/) {
print "△ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abc 001
× abc_002
△ defg 003
× defg004
└─────────────────────────────────────┘
◆任意の1文字
. : 任意の1文字と一致
┌─────────────────────────────────────┐
@datas = ( 'abc',
'abc0',
'def1',
'abc2' );
foreach $tmp (@datas) {
if ($tmp =~ /abc./) {
print "○ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
× abc
○ abc0
× def1
○ abc2
└─────────────────────────────────────┘
◆文字クラス
[文字A文字B・・・] (例)[ABC] : A or B or Cに一致
[^文字A文字B・・ ] (例)[^ABC] : A or B or C以外に一致
「-」で範囲指定もできる
(応用例) [a-c0-2] : a/b/c又は0/1/2に一致
[a-zA-Z] : 全てのアルファベットに一致
[0-9] : 全ての数字に一致
[ぁ-ん] : 全てのひらがなに一致
┌─────────────────────────────────────┐
@datas = ( 'abc',
'abC0',
'def1',
'abC2',
'abC3',
'abC4' );
foreach $tmp (@datas) {
if ($tmp =~ /[0c]/) {
print "○ ", $tmp, "\n";
} elsif ($tmp =~ /C[^1-3]/) {
print "△ ", $tmp, "\n";
} else {
print "× ", $tmp, "\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abc
○ abC0
× def1
× abC2
× abC3
△ abC4
└─────────────────────────────────────┘
◆連続文字
※このセクション以降、「文字」は「文字クラス」も含む。
文字* : 文字が連続で0個以上に一致
文字+ : 文字が連続で1個以上に一致
文字? : 文字が0個or1個あるパターンに一致
文字{数1} : 文字が連続で「数1」個あるパターンに一致
文字{数1,} : 文字が連続で「数値以上」個あるパターンに一致
文字{数1,数2} : 文字が連続で「数1以上,数2以下」個あるパターンに一致
┌─────────────────────────────────────┐
@datas = ( 'abc',
'abc0',
'abc00',
'abc000',
'abc0000',
'abc0def0',
'abc00000',
'abc00000a',
'abc000000',
'def0000000' );
print "1 2 3 4 5 6\n";
foreach $tmp (@datas) {
if ($tmp =~ /abc0*/) { print '* ' } #条件1
else { print '. ' }
if ($tmp =~ /abc0+/) { print '* ' } #条件2
else { print '. ' }
if ($tmp =~ /abc0?[a-zA-Z]/) { print '* ' } #条件3
else { print '. ' }
if ($tmp =~ /abc0{3}$/) { print '* ' } #条件4
else { print '. ' }
if ($tmp =~ /abc0{3,}$/) { print '* ' } #条件5
else { print '. ' }
if ($tmp =~ /abc0{3,5}$/) { print '* ' } #条件6
else { print '. ' }
print "$tmp\n";
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
1 2 3 4 5 6
* . . . . . abc
* * . . . . abc0
* * . . . . abc00
* * . * * * abc000
* * . . * * abc0000
* * * . . . abc0def0
* * . . * * abc00000
* * . . . . abc00000a
* * . . * . abc000000
. . . . . . def0000000
└─────────────────────────────────────┘
◆選択
文字列A | 文字列B : 文字列A or 文字列Bが含まれる
┌─────────────────────────────────────┐
@datas = ( 'abc',
'def',
'ghi',
'abcghi',
'ghidef',
'jkl'
);
foreach $tmp (@datas) {
if ($tmp =~ /abc|def/) {
print "○ ",$tmp,"\n";
} else {
print "× ",$tmp,"\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abc
○ def
× ghi
○ abcghi
○ ghidef
× jkl
└─────────────────────────────────────┘
◆単語の境界
\b : 境界文字(非英数字)なら一致
\B : 非境界文字(英数字)なら一致
↓ 実質的には以下のように使用することが多い
\b文字列\b : 文字列の前後が英文字以外(独立単語)なら一致
\B文字列\B : 指定文字列がある文字列の一部(独立していない)なら一致
┌─────────────────────────────────────┐
@datas = ( '私の名前はmonpeです',
'私の名前はmonpe2です',
'メールアドレスがmonpe@mail.jp (うそ)',
'Webmastermonperoom',
'全くの意味無し文字列',
'Webmaster monpe room'
);
foreach $tmp (@datas) {
if ($tmp =~ /\bmonpe\b/) {
print "○ ",$tmp,"\n";
} elsif ($tmp =~ /\Bmonpe\B/) {
print "△ ",$tmp,"\n";
} else {
print "× ",$tmp,"\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ 私の名前はmonpeです
× 私の名前はmonpe2です
○ メールアドレスがmonpe@mail.jp (うそ)
△ Webmastermonperoom
× 全くの意味無し文字列
○ Webmaster monpe room
└─────────────────────────────────────┘
◆後方参照
・既出の文字列を表現する。(パターン指定文字列内のみ)
(文字列a) 文字列 (文字列b) 文字列 \1 文字列 \2 文字列
ここで
\1 : 文字列a
\2 : 文字列b
を表す。\の後の数値は必要分付けられる。
┌─────────────────────────────────────┐
@datas = ( 'abcdefghi abcjklmn',
'abcdefghi jklmnopq'
);
foreach $tmp (@datas) {
if ($tmp =~ /(abc)defghi \1/) {
print "○ ",$tmp,"\n";
} else {
print "× ",$tmp,"\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
○ abcdefghi abcjklmn
× abcdefghi jklmnopq
└─────────────────────────────────────┘
◆マッチ文字列の利用
・マッチした部分文字列を利用する
(マッチ文字列1) 文字列 (マッチ文字列2) 文字列
$1 : マッチ文字列1
$2 : マッチ文字列2
┌─────────────────────────────────────┐
@datas = ( '品物A 価格 \1000 //備考1',
'品物B 価格 \2000',
'品物C 価格 \3000 //備考2',
'品物D 価格 \4000'
);
foreach $tmp (@datas) {
if ($tmp =~ /(品物\w) 価格 (\\\d+)/) {
print $1," : ",$2,"\n";
}
}
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
品物A : \1000
品物B : \2000
品物C : \3000
品物D : \4000
└─────────────────────────────────────┘
以上
[▲Perl Home▲]