便利な正規表現

正規表現の解説はいろいろあるので、ここでは便利に使えそうな表現をまとめます。

* はじめに

正規表現(Regular Expression)とは、文字列のパターンを表現する表記法です。主に文字列の検索/置換を行なうときに利用されます。正規表現は、通常の文字とメタキャラクタと呼ばれる意味を持った特別な記号を組み合わせて表記します。メタキャラクタとは、「^」という文字は「行の先頭」、「$」という文字は「行の末尾」、「.」は「任意の1文字」、「+」という文字は「直前の要素の1回以上の繰り返し」を意味します。

正規表現を利用すると、直接文字列を指定せずにあるパターンをしていするため、表記の揺れを吸収して検索したり置換を行ったりすることが出来ます。

* メタキャラクタ

まず、一般的に使われるメタキャラクタをちょっと紹介します。

メタキャラ
意味
.
任意の一文字を表します。
 c..l  -> cool, cowl, cull などがマッチ
*
前にある文字の0回以上を表します。
  ab*   -> a
ab
abb abbbbbbbbbbbbb などがマッチ
+
前にある文字の1回以上を表します。
  ab+   -> ab
abb abbbbbbbbbbbbb などがマッチ
?
前にある文字の0, 1回を表します。
  ab?   -> a
ab がマッチ
^
指定した文字から始まる
  ^ap   -> ap で始まる文字列がマッチ
$
指定した文字で終わる
  le$   -> le で終わる文字列がマッチ
[ ]
指定した複数の文字の中のいずれかを表します。
  [abc]   -> a, b, c がマッチ
  文字列の場合は、(be|is|was|been) という具合に ( ) | を使用する
連続したキャラクタ群を指定する場合、先頭と終端を - で繋いだ形で指定できます。
 [C-G]   -> [CDEFG]と同じ
はじめに^を指定した場合、キャラクタ群の補集合となります。
 [^F-K]  -> F, G, H, I, J, K 以外の文字
{ }
前にある文字の指定した回を表します。
  ab{3}   -> abbb にマッチ
ab{3,} -> abbb, abbbb, abbbbbbbb など 3回以上繰り返されたものにマッチ ab{3,5} -> abbb, abbbb, abbbbb にマッチ
( )
グループ化
1. 特殊変数 $1 の利用 $_ = "data=hello world"; /(.+)=(.+)/ ; print "Name= $1, Value= $2 \n";
( ) でくくられた文字列が特殊変数に割り当てられるので
Name= data, Value= hello world という結果が返ります。
2. 特殊変数 \1 の利用 /(..)\1/
( ) でくくられた文字列が特殊変数に割り当てられるので
abab, cdcd など2文字からなる文字列が2回以上続いていればマッチ
\w
英数文字またはアンダーバー。[a-zA-Z0-9_]と同等。
\W \w 以外の文字。
\d 数値文字。[0-9]と同等。
\D 数値以外の文字。[^0-9]と同等。
\s 空白文字。
\S 空白以外の文字。
\b ワードの先頭、あるいは末尾にマッチ。\bnoon\b は、noonにはマッチするが afternoon にはマッチしない。
\B ワード内の文字列にマッチ。\Bmile\B は、Smiles にはマッチするが mile にはマッチしない。
\A 文字列の最初にマッチ
\Z 文字列の最後にマッチ
\t タブ
\n 改行
\r キャリッジリターン

* マッチパターン演算子

演算子
意味
g
繰り返してマッチ
i
大文字、小文字の区別をしない
s
単一行として処理 (^ や $ は \n を無視)
m
複数行として処理 (^ は行先頭、$ は行末尾)
o
パターンを一度だけ展開
x
空白を無視、# をコメント処理

* 使えそうな表現

表現
意味
[ぁ-んー-]
ひらがなにマッチ
[ァ-ヶー-]
全角カタカナにマッチ
[0-9]{4}
4桁の数字にマッチ
[0-9]{1,3}
1から3桁の数字にマッチ
\"[^\"]*\"
引用符に囲まれた文字列
(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})
IPアドレス
(?=.*foo)(?=.*bar)
foo, bar を含むものにマッチ
(?:(?!foo).)*
foo を含まないものにマッチ
(?:\G|>)[^<]*?)
HTMLタグの外側 [Perl]
s/((?:\G|>)[^<]*?)foo/$1bar/g
HTMLタグの外にある foo を bar に変換 [perl]
PHP の preg_replace関数で使いたかったが、EUC では「スト」のなかに「好」の
コードが隠れているため間違ってマッチしてしまうことがある(たくさんあります)
そこで、一旦UTFにして処理する関数を作成(処理が遅くなります)
 
// $string に含まれる $replace を <b> タグで囲む
utf_preg_replace("/((?:\G|>)[^<]*?)($replace)/i", "\\1<b>\\2</b>", $string);
 
function utf_preg_replace($pattern, $replacement, $subject, $limit=-1) {
     $pattern  = mb_convert_encoding($pattern, "UTF-8", "eucjp-win");
     $replacement = mb_convert_encoding($replacement, "UTF-8", "eucjp-win");
     $subject  = mb_convert_encoding($subject, "UTF-8", "eucjp-win");
     $subject  = preg_replace($pattern, $replacement, $subject, $limit);
     $subject  = mb_convert_encoding($subject, "eucjp-win", "UTF-8");
     return $subject;
}
(\S+)://([^:/]+)(:(\d+))?(/[^#\s]*)(#(\S+))?
URL
$ascii = '[\x00-\x7F]';
$twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])';
$threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])';
$character = "(?:$ascii|$twoBytes|$threeBytes)";

EUC-JP文字