PHP入門 正規表現関数 正規表現パターンの修飾子

修飾子とは、正規表現でマッチングや置換を行う際に利用する動作オプションです。修飾子は「/パターン/修飾子」の形式で、正規表現の末尾に指定できます。

正規表現パターンの主な修飾子

修飾子概要
i大文字/小文字の区別を無視
m複数行検索に対応(改行の前後も文字列の末尾/先頭として認識)
s「.」が行末文字を含む任意の文字にマッチ(単一行モード)
xコメントの有効化
u正規表現パターンをUTF-8文字列として扱う

修飾子は「/~/im」のように、複数を同時に指定することもできます。

大文字/小文字を区別しない(i修飾子)

次のソースコードでは、HTTP部分にヒットしないため、置き換わりません。

<?php
$msg = <<<EOD
洋風亭のとんかつは予約は、次のHP(http://wwww.tonton.co.jp/)からご予約することができます。なお、仕出し弁当の
ご予約は、次のHP(HTTP://wwww31.shidasi.jp/yoyaku)からご予約お願い申し上げます。
EOD;
print preg_replace('|http(s)?://([\w-]+\.)+[\w]+(/[\w ./?%&=-]*)?|','<a href="$0">$0</a>', $msg);

そこで、i修飾子を利用します。

<?php
$msg = <<<EOD
洋風亭のとんかつは予約は、次のHP(http://wwww.tonton.co.jp/)からご予約することができます。なお、仕出し弁当の
ご予約は、次のHP(HTTP://wwww31.shidasi.jp/yoyaku)からご予約お願い申し上げます。
EOD;
print preg_replace('|http(s)?://([\w-]+\.)+[\w]+(/[\w ./?%&=-]*)?|i','<a href="$0">$0</a>', $msg);
実行結果
実行結果

複数行検索に対応する(m修飾子)

m修飾子は、マルチラインモードを表します。

マルチラインモードを無効にした場合の結果

<?php
 $str = "7人の賢者には101の宝玉が与えられた。";
 if(preg_match_all('/^[0-9]{1,}/',$str, $data)){
  foreach ($data[0] as $item){
    print"マッチング結果:{$item}<br />";
  }
 }
実行結果
実行結果

マルチラインモードを有効にした結果。改行の後方に位置する「101」もマッチング結果に加わります。マルチラインモードを有効にすると、正規表現パターン「^」は「行頭」を意味するようになる。結果、先頭の「7」はもちろん、改行コード「\n」の直後にある「101」にもマッチすることになります。これは「$」についても同様です。マルチラインモードを有効にした場合は、「$」は行末にもマッチします。

<?php
 $str = "7人の賢者には\n101の宝玉が与えられた。";
 if(preg_match_all('/^[0-9]{1,}/m',$str, $data)){
  foreach ($data[0] as $item){
    print"マッチング結果:{$item}<br />";
  }
 }
実行結果
実行結果
最初から文字列の先頭/末尾を検出するなら、「\A」「\z」を優先して使用したほうがよいです。動作モードにかかわらず、常に入力文字列の先頭/末尾を意味します。

シングルラインモードを有効にする

シングルラインモード(単一行モード)とは、「.」の挙動を変更するためのモードです。

シングルラインモードが無効の場合

既定では正規表現「.」は「\n」(改行)を除く任意の文字にマッチします。よって、この場合であれば、文字列先頭(\A)から改行の前までがマッチング結果として得られます。

<?php
 $str = "7人の賢者には\n101の宝玉が与えられた。";
 if(preg_match_all('/\A.+/',$str, $data)){
  foreach ($data[0] as $item){
    print $item;
  }
 }
実行結果
実行結果

シングルラインモード(s修飾子)を有効にする

この場合「.」は改行文字も含むようになります。結果、改行をまたがってすべての文字列にマッチするようになります。

<?php
 $str = "7人の賢者には\n101の宝玉が与えられた。";
 if(preg_match_all('/\A.+/s',$str, $data)){
  foreach ($data[0] as $item){
    print $item;
  }
 }
実行結果
実行結果

正規表現を見やすく整形する(x修飾子)

x修飾子を有効にすることで、正規表現に空白/コメントを付与できるようになります。

例:正規表現をx修飾子を有効化した状態で書き換えたパターン

x修飾子を有効にした場合、正規表現内の空白/改行は無視され、また、行末に「#」コメントを加えられるようになります([…]内の空白などは維持されます)。

<?php
 $str = "仕事のメールアドレスは、test@gmail.comです。";
 if(preg_match("/
                [a-z0-9.!#$%&'*+\/=?^_{|}~-]+ #local
                @                             #delimiter
                [a-z0-9-]+(\.[a-z0-9-]+)*     #domain
                /x",$str,$data)){
  print "Mail:{$data[0]}";
 }
 
実行結果
実行結果

埋め込みフラグ

正規表現オプションは、正規表現パターンの末尾で指定する他、埋め込みフラグ(インラインフラグ)として指定することもできます。

以下のコードは同じ意味になります。

preg_match("/[a-z0-9.!#$%&'*+\/=?^_{|}~-]+@[a-z0-9-]+
(\.[a-z0-9-]+)*/i", $str,$data)
preg_match("/(?i)[a-z0-9.!#$%&'*+\/=?^_{|}~-]+@[a-z0-9-]+
(\.[a-z0-9-]+)*/i", $str,$data)

(?フラグ)の形式で、正規表現パターンの中に埋め込みます。ただし、フラグの適用範囲は埋め込み場所によって変化します。

例えば、上記のパターンの先頭で宣言しているので、パターン全体に適用されますが、以下のように途中に埋め込むこともできます。

preg_match("/[a-z0-9.!#$%&'*+\/=?^_{|}~-]+@(?i)[a-z0-9-]+
(\.[a-z0-9-]+)*/i", $str,$data)

この場合は、指定された以降でのみフラグは有効になります。よって、上の例であれば「xxxxx@gmail.com」「xxxxx@GMAIL.COM」にはマッチしますが、「XXXXX@GMAIL.COM」にはマッチしません。

トップレベル(=サブパターンの外)でフラグ定義された場合です。サブパターンの配下で定義されたフラグ定義は、宣言以降、サブパターンの終わりまで有効となります。

(?-フラグ)の形式で、パターンの途中で一旦有効にしたフラグを無効にすることもできます。

preg_match("/(?i)[a-z0-9.!#$%&'*+\/=?^_{|}~-]+@(?-i)[a-z0-9-]+
(\.[a-z0-9-]+)*/i", $str,$data)

さらに、複数のフラグを組み合わせて、(?im-x)のような表記も出来ます。この場合、i、mフラグが有効になりxフラグを無効化します。