Perlの正規表現|文字列の検索・置換など正規表現の基本的な使い方
正規表現とは、文字列の一部をパターン化して表現する方法です。
文章の中からある文字列を検索する時、検索したい文字列をそのまま指定するのではなく、文字列の一部をパターン化して検索する(パターンに基づいた仮の文字列を作成して検索する)場合などに正規表現を使います。
例えばWindowsやLinuxでも、ファイルや文字列を検索するときに使用される正規表現として「*」(ワイルドカード)が知られていると思います。パターンを『app*』と表現すると、「apple」「application」などが含まれるファイル、文字列がマッチします。
Perlの場合、他の言語に比べて非常に有用な正規表現によるパターンマッチ機能が実装されており、より簡単に、かつ詳細にパターンマッチを実行することができます。
目次
1.基本的な使い方
Perlでは正規表現を「パターン」と呼ぶことが多いです。文字列に対してパターンがマッチすれば(成功すれば)真を返し、マッチしなければ(失敗すれば)偽を返します。
パターンはスラッシュで囲んで指定します。この場合のスラッシュのように正規表現を囲む記号を「デリミタ」と呼びます。
$_ = 'abcdefg'; if (/cde/) { print 'マッチしました'; } else { print 'マッチしませんでした'; }
例では、条件判定のところにパターンだけ記述されていて文字列が何も指定されていません。この場合はデフォルト変数「$_」に対してcdeが含まれているかのマッチングを行います。その他の変数に対してマッチングを行うには、結合演算子『=~』を使用します。
my $word = 'abcdefg'; if ($word =~ /cde/) { print 'マッチしました'; } else { print 'マッチしませんでした'; }
Perlでは、正規表現を使用する場合に特別な関数をタイプする必要はありません。また、パターンマッチを行う際は「!~」を使うこともできます。「!~」はパターンがマッチすれば(成功すれば)偽を返し、マッチしなければ(失敗すれば)真を返します。
my $word = 'abcdefg'; if ($word !~ /cde/) { print 'マッチしませんでした'; } else { print 'マッチしました'; }
2.文字列を検索 ~ パターンマッチ演算子「m//」
スラッシュでパターンを囲むのは、実際はパターンマッチ演算子「m//」のショートカットを意味します。「m」を明示することによって任意のデリミタを使用できるようになります。デフォルトのスラッシュを使う場合には「m」を書く必要はありません。
任意のデリミタは、よく使われる「m{pattern}(ブレース)」のように対になった記号や、「m%pattern%」のように1種類の記号で始まりと終わりを囲む方法が使えます。当然ですが、パターンの中で使用しない記号を選ばなければなりません。例えばURLのような書式は、デリミタがスラッシュのままではエスケープが多くなり、見難くなってしまうので、あまりURLに登場しない記号をデリミタに使います。
my $url = 'http://example.com/'; print ($url =~ m{^https://} ? 'HTTPSです' : 'HTTPSではありません');
3.文字列を置換 ~ 置換演算子「s///」
文字列の置換には「s///」を使用します。「s/パターン/置換文字列/」のような形式で表記し、パターンにマッチした文字列を全て置換文字列に置き換えます。マッチに失敗した場合は変数の値は変わりません。
my $url = 'http://example.com/'; $url =~ s%^http://%https://%; print $url; > https://example.com/
また「m//」と同じく任意のデリミタを指定することができます。デフォルトのスラッシュを使う場合でも「s」は必要です。ブレースのように対になったデリミタは、パターンを一度閉じるようにデリミタを4つ使って表記します。最初のパターンのデリミタと置き換え文字列のデリミタを違うカッコにすることも可能です。
my $url = 'http://example.com/'; $url =~ s{^http://}(https://); print $url;
4.特殊文字 ~ メタキャラクタ
実際のソースコード上は、基本的な使い方の例にあげた「cde」のような固定文字列にマッチさせることはあまりありません。そのために正規表現では特殊な意味を持つメタキャラクタが用意されています。
サンプル
\ | ( ) [ ] { } ^ $ * + ? .
4-1.文字クラス
メタ文字 | 意味 |
.(ドット) | ワイルドカード。改行を除くあらゆる1文字にマッチ。 |
[…](角括弧) | 文字クラス。カッコ内の文字のどれか1つにマッチ。 |
\d | 数字。[0-9]と同じ。 |
\D | 数字以外。[^0-9]と同じ。 |
\w | 単語構成文字。[a-zA-Z0-9_]と同じ。 |
\W | 単語構成文字以外。[^a-zA-Z0-9_]と同じ。 |
\s | 空白文字。[ \t\n\r\f]と同じ。 |
\S | 空白文字以外。[^\t\n\r\f]と同じ。 |
my $word = 'Apple, Orange, Grape, Banana, Peach'; if ( $word =~ /A.O/ ) { print "'A'と'O'の間に1文字見つかりました。\n"; } if ( $word =~ /[AB]/ ) { print "'A'と'B'が見つかりました。\n"; }
文字クラスの中では、–(ハイフン)を使って文字の範囲を指定することができます。[a-z]とすれば小文字アルファベットaからzまでのどれかにマッチします。[a-zA-Z]は大文字小文字のアルファベット、[b-e]はbからeまでのアルファベットどれかにマッチします。[0-9]は0から9の数字にマッチします。
my $word = 'abcdefg'; if ( $word =~ /[a-z]/ ) { print "小文字のアルファベットが含まれています。"; }
場合によっては含まれない文字を探した方が早い場合もあります。文字クラスの先頭に^(キャレット)を置くと、指定した文字以外の文字にマッチするようになります。
my $word = 'abcdefg'; if ( $word =~ /[^a-zA-Z0-9]/ ) { print "半角英数字以外の文字が含まれています。"; }
^(キャレット)は、下で示す位置指定でも使用されるメタキャラクタです。混同しないように注意しましょう。
4-2.グループと選択
メタ文字 | 意味 |
(…)(丸括弧) | 文字列のグループ化。カッコ内の文字列をひとつの文字として扱う。 |
|(垂直バー) | 選択肢。どちらか一方にマッチ。 |
my $word = 'Apple, Orange, Grape, Banana, Peach'; if ( $word =~ /(Apple|Grape)/ ) { print "'Apple'か'Grape'が含まれています。\n"; }
4-3.位置指定
メタ文字 | 意味 |
^(キャレット) | 文字列の先頭または行頭にマッチ。 |
$(ドル記号) | 文字列の末尾または行末にマッチ。 |
my $word = 'Apple, Orange, Grape, Banana, Peach'; if ( $word =~ /^Apple/ ) { print "' Apple'から始まっています。\n"; } if ( $word =~ /Peach$/ ) { print "'Peach'で終わっています。\n"; }
4-4.繰返し指定
メタ文字 | 意味 |
*(アスタリスク) | 0個以上でマッチ。文字が無くてもマッチ。 |
+(プラス) | 1個以上でマッチ。 |
?(クエスチョン) | 0個または1個にマッチ。 |
{COUNT}(繰り返す数) | きっかりCOUNTの回数繰り返す。 |
{MIN,}(最低回数,) | MINの回数以上繰り返す。 |
{MIN,MAX}(最低回数,最高回数) | MINの回数以上MAXの回数以下繰り返す。 |
my $word = 'abcdeeeeefghjiklmnopppppqrstuvwxyz'; ^^^^^ ^^^^^ if ( $word =~ /e+/ ) { # $&には直前にマッチした文字列が入ります。 print "$&\n"; } > eeeee
繰返し指定は可能な限り多くの文字をマッチさせます。これを「最長マッチ」と言います。一方、出来る限り少ない文字でマッチさせることを「最短マッチ」と言います。最小マッチさせるには、最長マッチの繰返し指定の後に「?」を追加します。
メタ文字 | 意味 |
*? | 0個以上でマッチ。文字が無くてもマッチ(最短マッチ)。 |
+? | 1個以上でマッチ(最短マッチ)。 |
?? | 0個または1個にマッチ(最短マッチ)。 |
{MIN,}? | MINの回数以上繰り返す(最短マッチ)。 |
{MIN,MAX}? | MINの回数以上MAXの回数以下繰り返す(最短マッチ)。 |
my $word = 'abcdeeeeefghjiklmnopppppqrstuvwxyz'; ^^^^^ ^^^^^ if ( $word =~ /e+?/ ) { print "$&\n"; } > e
5.オプション修飾子 ~ フラグ
正規表現の動作を変更できる「オプション修飾子」があります。単に「オプション」とか「フラグ」と呼ばれることもあります。オプションは最後のデリミタの直後に指定します。複数オプションはまとめて指定することもできます。
オプション | 意味 |
/i | 大文字と小文字を区別せずにマッチする。 |
/m | ^や$が行頭や行末にマッチするようにする。 |
/s | ワイルドカードの.(ドット)を改行にもマッチさせる。 |
/x | パターンにある空白文字を無視してコメントを書けるようにする。 |
/o | パターンのコンパイルを一回だけ行う。 |
/g | グローバルマッチ。すべてのマッチを見つける。置換時はs///はすべて置き換える。 |
/e | 置換時のみ。置き換え文字列を式として評価する。 |
my $word = 'This book is 500 yen.'; $word =~ s/(\d+)/$1*2/e; print "$word\n"; > This book is 1000 yen.
6.最後に
正規表現が本領を発揮するのは、マッチした部分を切り出して再利用する場合や、置換・削除する時です。これらの例を参考に、皆さんも多くの正規表現を使ってみてはいかがでしょうか。
コメント