読者です 読者をやめる 読者になる 読者になる

アルパカDiary Pro

はてなブログProではありません

初めてのPerlを読み返す 7−9章 正規表現

Perl 勉強

初めてのPerl
初めてのPerl
posted with amazlet at 09.04.05
ランダル・L. シュワルツ トム フェニックス
オライリージャパン
売り上げランキング: 34126


この記事のスタンスはこちら


今回は正規表現関係をまとめちゃいました。
ちなみに正規表現の基本的な部分はこちらを参考にすると良いです。

7章 正規表現の基本*1

  • 正規表現とファイル名マッチに使うパターン(グロブ)*2は違うものだよ!
  • 単純なパターンの例
$_="hetare engineer";
if(/engineer/){
  print "It matched!!\n";
}
  • ドット「.」は、改行文字を除いたあらゆる1文字にマッチする。
  • 量指定子
* 直前に置かれた任意の文字に0回以上マッチする
+ 直前に置かれた任意の文字に1回以上マッチする
? 直前に置かれた任意の文字に0回または1回だけマッチする
  • 「.*」は全ての文字列にマッチするため、ガラクタパターンと呼ばれる。
  • ()で囲むとパターンをグループ化できる。
  • 縦棒「|」でORパターンになる。
  • パターンをテストするプログラム(詳細は9章)
#|/user/bin/perl
while(<>){
  chomp;
  if(/パターン/){
    print "Matched: |$`<$&>$'|\n";
  }else{
    print "No match.\n";
  }
}

8章 正規表現の詳細

  • 文字クラスは1対のブラケット[]の間に文字を並べたもの。
$_ = "toritori0318";
# 「toritori」の後に、数値が1つ以上存在する場合にマッチする
if(/toritori[0-9]+/){
  print "toritori match!!\n";
}
  • 文字クラスの先頭に「^」を置くと、否定になる。(文字クラスではない「^」と混同しやすいので注意)。
  • 文字クラスのショートカット
説明 ショートカット 文字クラス
数値 \d [0-9]
数値以外 \D [^0-9]
ワード文字 \w [A-Za-z0-9_]
ワード文字以外 \W [^A-Za-z0-9_]
空白文字 \s [\f\t\n\r ]
空白文字以外 \S [^\f\t\n\r ]
  • 繰り返し回数を指定する場合、「{最小繰り返し回数,最大繰り返し回数}」で指定できる。省略した場合は回数無制限。
$_ = "toritoritori0318";
# 文字「tori」を「2〜無制限」繰り返したものにマッチする
if(/(tori){2,}/){
  print "toritori match!!\n";
}
  • アンカー
^ 文字列の先頭を表す
$ 文字列の末尾を表す
\b ワードアンカー。ワードの境界を表す。
\B 非ワードアンカー。非ワードの境界を表す。
$_ = "linux xen perl java postgres etc";
# 先頭が「linux」で、末尾が「etc」の場合にマッチする
if(/^linux(.*)etc$/){
  print "linux etc match!!\n";
}
# 「postgres」というワードにマッチする
if(/\bpostgres\b/){
  print "postgres match1!!\n";
}
# 「postgre」というワードは存在しないため、マッチしない!
if(/\bpostgre\b/){
  print "postgres not match..\n";
}
# 「postgre」の後ろが非ワードアンカーのため、これはマッチする!
if(/\bpostgre\B/){
  print "postgres match2!!\n";
}
  • 後方参照は、それまでに保存した正規表現のメモリの値を参照。
$_ = "'toritori0318'";
# 「'」の後ろに「'」があるような文字列にマッチする
if(/(').*\1/){
  print " '' match!!\n";
}
  • 優先順位
1 カッコ ()
2 量指定子 * + ?
3 アンカーと並び ^ $ \b \B
4 縦棒 |(これは全角ですが、実際は半角です)

9章 正規表現の利用法

  • 今までの「//」というのは、実は「m//」のショートカット。デリミタは自由に変更できるので「m()」としたり、「m!!」と書いたりも出来る。
  • オプション修飾子
i 大文字と小文字を区別せずにマッチ
s あらゆる文字にマッチ(ドットを改行文字にもマッチさせる場合)
  • オプション修飾子は、正規表現の閉じデリミタの直後に指定する。「m/パターン/i」みたいな。
  • 結合演算子「=~」を使う事により、「$_」ではなく任意の文字列にマッチさせることが出来る。
my $aaa="toritori0318";
if($aaa =~ /toritori/){
  print "toritori match!!\n";
}
  • パターンに変数を使う事も可能(変数の値がパターンに展開される)。
  • マッチ変数により、マッチした部分を取り出すことが可能。
my $aaa="linux xen perl";
if($aaa =~ /(\S+) (\S+) (\S+)/){
  print "words were $1 $2 $3\n";
}
  • マッチ変数は、次のパターンマッチに成功するまでメモリ上に残っていることに注意!
  • 自動マッチ変数(7章の「パターンをテストするプログラム」の説明だよ!)
$` マッチした部分より前にあるものがセットされる
$& マッチした部分全体がセットされる
$' マッチした部分より後ろにあるものがセットされる
  • 自動マッチ変数をスクリプト内で使う事により、正規表現のスピードが遅くなるらしい…
  • 「s///」演算子で置換を行うことが出来る。「m//」と同様に、デリミタを変更することも可能。
$_ = "toritori0318";
# 「tori」を「hoge」に置換
s/tori/hoge/;
# 「g」オプションにより、全ての置き換えを行う。
s/tori/hoge/g;
  • 大文字と小文字の変換
\U 全体を大文字変換
\L 全体を小文字変換
\E \Uと\Lを使用している時、¥E以降の置き換えを中止する
\u 次の1文字だけ大文字変換
\l 次の1文字だけ小文字変換
$_ = "linux xen PERL java POSTGRES etc";
s/(\w+) (\w+) (\w+) (\w+) (\w+) (\w+)/\U$1 $2 $3 $4 $5 $6/gi;
print "$_\n"; # LINUX XEN PERL JAVA POSTGRES ETC
s/(\w+) (\w+) (\w+) (\w+) (\w+) (\w+)/\L$1 $2 $3 $4 $5 $6/gi;
print "$_\n"; # linux xen perl java postgres etc
s/(\w+) (\w+) (\w+) (\w+) (\w+) (\w+)/\U$1 $2 $3 \E$4 $5 $6/gi;
print "$_\n"; # LINUX XEN PERL java postgres etc
s/(\w+) (\w+) (\w+) (\w+) (\w+) (\w+)/\l$1 $2 $3 $4 \u$5 $6/gi;
print "$_\n"; # lINUX XEN PERL java Postgres etc
  • split関数で、デリミタ毎のリストに分割する。
@fields = split /:/, ":::a:b:c:::"; # ("","","","a","b","c") というリストを返す。後ろの空フィールドは捨てられる。
  • split関数のデフォルトは、「$_」の内容を「空白文字」で分割する。
@fields = split;    # split /\s+/, $_; と似ているが、先頭のスペースも捨てられてしまう!
  • join関数で、指定したデリミタでリストを接着する。
my $join = join ":", 1,2,3,4; # 1:2:3:4


完全なる自分用の備忘録ですね。

*1:以下引用をいくつか含みます

*2:*.pm みたいなの