いつまで経っても正規表現が覚えられないので、整理してみました。
正規表現については他言語と共通な部分もあるかと思いますが、基本PHP前提です。
目次
- 1. 検索関数、置換関数の使い方
- 2. パターン修飾子(オプション)
- 3. 文字の意味
- 4. エスケープシーケンス
- 5. 解説が必要な項目
- 5-1. 最短マッチ(最短一致)
- 5-2. キャプチャグループ
1. 検索関数、置換関数の使い方
単純な文字列ではなく、あるパターンに当てはまる文字を検索したり、置換したい場合に、下記関数とセットで正規表現を使用します。
文字列検索 (preg_match関数) ※1個だけ検索
//構文
preg_match( $pattern, $str, $matches);
// ABCから始まる文字列を検索
preg_match('/^ABC.+$/', 'ABCDE', $matches);
var_dump($matches);
//array (
// [0]=>"ABCDE",
//)
echo $matches[0]; //ABCDE
$patternについて
$patternは/(スラッシュ)で囲みます
/で囲まれた部分が正規表現(パターン)になります
2番目の/の後にパターン修飾子(オプション)を指定できます。なくてもOK。
文字列検索 (preg_match_all関数) ※すべて検索
//構文
preg_match_all( $pattern, $str, $matches);
// 複数行の文字列に対して、ABCから始まる文字列を"全て"検索
$str = "ABCDE
ABCFGH
IJKLMN";
preg_match_all('/^ABC.+$/m', $str, $matches);
var_dump($matches);
//array (
// [0]=>array (
// [0]=>"ABCDE",
// [1]=>"ABCFGH",
// ),
//)
echo $matches[0][0]; //ABCDE
echo $matches[0][1]; //ABCFGH
文字列置換 (preg_replace関数)
//構文
preg_replace($pattern, $replace, $str);
// ABCから始まる文字列をFGHに置換する
echo preg_replace('/^ABC.+$/', 'FGH', 'ABCDE'); //FGH
2. パターン修飾子(オプション)
修飾子 | 意味 |
---|---|
なし | 1行目の文字列だけ対象とする。 |
i | 小文字大文字を区別しない。 |
m | 複数行の文字列として扱う。 ※行ごとに処理したい場合などに指定 |
s | 改行を無視して1行の文字列とみなす。 ※改行があるhtml要素を処理したい場合などに指定 |
u | UTF-8として処理する。 ※日本語を処理したい場合などに指定 |
3. 文字の意味
正規表現には一つの文字で複数の意味を表すものがあります。
すべてではありませんが、よく使うものをぱっと見ですぐわかるようにまとめました。
太字は大まかな意味。
文字 | 意味① | 意味② |
---|---|---|
[] | 文字クラス。[ ]内のいずれかの1文字。 [abc] (aかbかcに一致) [a-z] (小文字アルファベット1文字に一致) [0-9] (数字1桁に一致) |
|
^ | 位置指定。直後の文字列から始まる 例) ^abc (abcから始まるabcに一致) |
文字クラス否定。角括弧の中で直後の文字を否定。 例) [^abc] (aかbかc以外の文字列に一致) |
$ | 位置指定。直前の文字列で終わる。 例) abc$ (末尾がabcで終わるabcに一致) |
|
. | 任意の文字。任意の1文字。 | |
? | 繰り返し。直前の文字が0または1文字。 例) @? (@があってもなくても一致) |
最短マッチ。繰り返し文字とセットで指定する。詳しくは下記 5-1. 最短マッチ(最短一致)で解説。 |
* | 繰り返し。直前の文字を0個以上繰り返し。 例) .* (0文字以上の任意の文字列に一致) |
|
+ | 繰り返し。直前の文字を1個以上繰り返し。 例) .+ (1文字以上の任意の文字列に一致) |
|
{n} | 繰り返し。直前の文字をn個繰り返し。 例) [0-9]{3} (3桁の数字に一致) |
|
{n,} | 繰り返し。直前の文字をn個以上繰り返し。 例) [0-9]{3,} (3桁以上の数字に一致) |
|
{,n} | 繰り返し。直前の文字をn個以上繰り返し。 例) [0-9]{,3} (3桁以下の数字に一致) |
|
{n,m} | 繰り返し。直前の文字をn〜m個繰り返し。 例) [0-9]{1,3} (1〜3桁の数字に一致) |
|
() | グループ化。範囲の限定。 例) (abc)+ (abcを繰り返す文字列に一致) |
キャプチャグループ。()で囲んだパターンを後方で取得する。詳しくは下記 5-2. キャプチャグループ |
\ | エスケープ文字。後に続く、特別な意味を持つ文字をただの文字列にする。
例) \/ (「/」文字列に一致) |
エスケープシーケンス。後に続く文字と一緒にキーボードから入力できない特殊な文字を意味する。下記 4. エスケープシーケンスに一覧記載。 例) \n (改行に一致) |
| | 条件式。または。 例) A|B (AまたはBに一致) |
4. エスケープシーケンス
\(バックスラッシュ)と、後に続く文字とセットで、キーボードから入力できない特殊な文字を意味します。PCの規定であらかじめ決められています。
文字 | 意味 |
---|---|
\n | 改行 |
\t | タブ |
\d | 数字 ※[0-9]と同義 |
\D | 数字以外の文字 ※[^0-9]と同義 |
\s | 空白文字 (半角スペース、全角スペース、タブ、改行、改ページ含む) |
\S | 空白以外の文字 |
5. 解説が必要な項目
5-1. 最短マッチ(最短一致)
"?"は最短マッチを意味します。言葉で説明するより例を見た方が理解が早いのでさっそく。
クラス名がtestのdiv要素を、閉じタグまで取得したい
$str = '<div><div class="test">テスト</div></div>';
// ?をつけない (デフォルトでは最長マッチ)
$pattern = '/<div class="test">.+<\/div>/';
if ( preg_match($pattern, $str, $matches) ) {
echo htmlspecialchars($matches[0]); //<div class="text">テスト</div></div>
}
// ?をつける (最短マッチ)
$pattern = '/<div class="test">.+?<\/div>/';
if ( preg_match($pattern, $str, $matches) ) {
echo htmlspecialchars($matches[0]); //<div class="text">テスト</div>
}
.+に?を加えることで、後に続く</div>を最短で切り上げてマッチさせることができます。
最短マッチの?は、繰り返しを意味する文字(量指定子)の後に指定します。
「*」、「+」、「{n,m}」など文字ですね。
最短マッチは結構使うので覚えておくと便利
5-2. キャプチャグループ
パターンに一致する文字列を検索し、そこから部分的に文字列を取得したい時があります。
その部分的な文字列を()で囲んだものをキャプチャグループと呼びます。
キャプチャグループは後方(今回だと$matches)で取得できます。
http://abc/から"abc"だけを取得したい
$str = 'http://abc/';
$pattern = '/^http:\/\/(.+)\/$/'; // "http://"で始まり"/"で終わる文字列をマッチさせる
preg_match($pattern, $str, $matches);
var_dump($matches);
//array (
// [0]=>"http://abc/",
// [1]=>"abc",
//)
preg_matchは全体マッチした文字列が$matches[0]に入り、キャプチャグループで指定した文字列が$matches[1]以降に代入されます。
キャプチャグループが複数ある場合、前から順番に$matches[1]、$matches[2]と値が代入されます。
これがpreg_match_all関数だとまた違った値代入になりますが、それは別途書こうと思います。