正規表現

予備知識

意味を持つ文字

[ ] ( ) < > { } |
^ ? ! # \ $ =  - + * , .
  • 単なる文字列として正規表現内に書く場合は先頭に \ を置いてエスケープする必要がある
  • 変数を正規表現内に書く際にも変数内のエスケープが必要
  • 文字の \ は \\ で表現する。

グループ

  • 丸括弧 () で囲まれた範囲。
    正規表現内での1つの範囲制限となり、この範囲は後方参照の候補にあがる。

後方参照

  • グループに応じて $1 $2 $3のような対応した変数に値がセットされ、
    正規表現内でも\1 \2 \3のようにグループに対応する文字列を利用できる。
  • (?:regexp)で明示的に後方参照を禁じたグループはこの候補には上がらず飛ばされる。

最短一致

  • n〜m個のマッチは特に明示がない限りはなるべく長い文字列を取るが、
    最短一致を使うと最もnに近くなるように働く。

最長一致/バックトラック

  • n〜m個のマッチは特に明示がない限りはなるべく長い文字列を取り、
    それでマッチしない場合は徐々に文字数を減らす「妥協」が行われるが
    バックトラックを使うとn〜m個の指定で最もmに近くなるように働く。
    例え正規表現で真にならなくても最長一致の指定部分は最長を取る。
    • 例えば、/(a*+)a/ は()内で全てのaが消費されるため決してマッチしない。

パターン修飾子

i
半角英字の大文字と小文字を区別しない
m
文字列が複数行あると判断する。
つまり先頭と末尾の位置指定で改行文字を考慮しなくなる。
未指定
先頭を示す ^ は文字列の最初と行頭(改行ごとの区切りの先頭)にマッチし、
末尾を示す $ は文字列の最後と行末(改行ごとの区切りの末尾)にマッチする。
m を指定
先頭を示す ^ は文字列の最初だけにマッチし、
末尾を示す $ は文字列の最後だけにマッチする。
s
ピリオドが改行文字も含むすべての文字にマッチする。
指定しない場合は . は改行にはマッチしない。
x
e
後方参照の置き換えを行った後、文字列をスクリプトとして実行する。
A
D
S
U
X
u

構文

*?
*の最短一致。0個以上にマッチ
+?
+の最短一致。1個以上にマッチ
??
?の最短一致。0〜1個にマッチ
{n}?
{n}の最短一致。n個にマッチ
{n,}?
{n,}の最短一致。n個以上にマッチ
{n,m}?
{n,m}の最短一致。n〜m個にマッチ
*+
*でバックトラックしない。0個以上にマッチ
++
+でバックトラックしない。1個以上マッチ
?+
?でバックトラックしない。0〜1個にマッチ
{n}+
{n}でバックトラックしない。n個にマッチ
{n,}+
{n,}でバックトラックしない。n個以上にマッチ
{n,m}+
{n,m}でバックトラックしない。n〜m個にマッチ

拡張構文

(?#text)
コメント文
(?:regexp)
後方参照をしない。つまり括弧で囲むが$1,$2...\1,\2...等に値をセットしない。
regexp1(?=regexp2)
前方一致検索。()内は置き換え要素にならない
/regexp1regexp2/と同様のマッチングで真となるが、マッチした部分はregexp1だけと解釈する。
$str = 'abcdef';
$str =~ s/bc(?=de)/X/;
print $str;
実行結果
aXdef
regexp1(?!regexp2)
前方一致の否定形。()内は置き換え要素にならない
/regexp1regexp2/にならない時のマッチングで真となるが、マッチした部分はregexp1だけと解釈する。
$str = 'abcdef';
$str =~ s/bc(?!xy)/X/;
print $str;
実行結果
aXdef
(?<=regexp1)regexp2
後方一致検索。()内は置き換え要素にならない /regexp1regexp2/と同様のマッチングで真となるが、マッチした部分はregexp2だけと解釈する。
$str = 'abcdef';
$str =~ s/(?<=bc)de/X/;
print $str;
実行結果
abcXf
(?<!regexp1)regexp2
後方一致検索の否定形。()内は置き換え要素にならない /regexp1regexp2/にならない時のマッチングで真となるが、マッチした部分はregexp2だけと解釈する。
$str = 'abcdef';
$str =~ s/(?<=xy)de/X/;
print $str;
実行結果
abcXf
(?>regexp)
バックトラックしない。()内の式に最長一致し、妥協しない。

Perl 以外との比較

秀丸エディタ

  • 数字のエスケープシーケンス \d に相当するものがない
    数字を表わすには [0-9] を使う。
  • \w が英字とアンダーバーのみを表わす。
    数字は含まないため [A-Za-z_] と同等。

PHP

  • Tech/PHP
  • 意味を持つ文字
    . \ + * ? [ ^ ] $ ( ) { } = ! < > | :
    \r \t \d \D \w \W \b \B \xHH
    あたりは基本的にPerlと同様の意味を持っています。
    • ereg で始まる関数は\s、\S、\f は使えません
      空白文字のまとまりを示す \s がない代わりに
      [ \t\n\x0b\x0c\r] と等価の [[:space:]][ \t] と等価の [[:blank:]] があります。
      ただし、[ \t\n\r\f] と等価の \s の完璧な互換にはなれません。長いし。
  • 文字の \ の正規表現は \\\\ で表わします。
  • 二種類の正規表現関数
    • ereg で始まるphp用の正規表現関数。
      $str2 = ereg_replace('/^(\w+)/', 'header : \\1', $str);
      ぶっちゃけ、ereg は速度や便利さで劣るためあまり使われない。
    • preg で始まる Perl 互換の正規表現関数。
      ただし、特殊記号の違いなど完璧に互換にはならない。
      正規表現にはデリミタ(区切り文字)として先頭と最後を / や # などで区切る必要がある。
      $str2 = preg_replace('/^(\w+)/', 'header : $1', $str);
      • 後方参照の置き換えに ereg_ の表現である \\0 \\1 \\2 \\3 も使えますが、
        preg_ では $0 $1 $2 $3 の使用が推奨されます。
        ${数字} とすることで区切ることができ、$11 と ${1}1 のような区別ができます。
  • マッチング
    <?php	// 2つとも真になる
    $str = 'xyz0x410x420x43';
    if( ereg('0x([0-9a-fA-F]){2}', $str) )		echo "ereg\n";
    if( preg_match('/0x([0-9a-fA-F]){2}/',$str) )	echo "preg_match\n";
    ?>
  • 英字の大小を区別しないマッチング
    <?php	// 2つとも真になる
    $str = 'xyz0x410x420x43';
    if( eregi('0x([0-9A-F]){2}', $str) )		echo "eregi\n";
    if( preg_match('/0x([0-9A-F]){2}/i',$str) )	echo "preg_match\n";
    ?>
  • 置き換え
    <?php	// 2つとも "xyzHexHexHex\n" が返る
    $str = 'xyz0x410x420x43';
    echo ereg_replace('0x([0-9a-fA-F]){2}',   'Hex', $str) . "\n";
    echo preg_replace('/0x([0-9a-fA-F]){2}/', 'Hex', $str) . "\n";
    ?>
  • 英字の大小を区別しない置き換え
    <?php	// [0-9A-F] で英小文字も対応させる
    	//2つとも "xyzHexHexHex\n" が返る
    $str = 'xyz0x410x420x43';
    echo  eregi_replace('0x([0-9A-F]){2}',   'Hex', $str) . "\n";
    echo  preg_replace('/0x([0-9A-F]){2}/i', 'Hex', $str) . "\n";
    ?>
  • 置き換えた文字ごとに関数を実行する
    <?php	// "xyzABC\n" が返る
    $str = 'xyz0x410x420x43';
    echo  preg_replace('/0x([0-9A-F]){2}/ie', 'chr($0)', $str) . "\n";
    ?>

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規新規下位 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-01-28 (月) 18:56:09 (3435d)