定義と使い方
- PHPバージョン
- 4+
preg_match_all() 関数は、正規表現を使用して、指定された文字列から一致するすべての部分を検索し、その結果を返します。
特徴
- この関数は、大文字と小文字を区別します。
- 正規表現パターンと一致するすべての部分文字列を検索し、その個数を整数で返します。一致するものがなければ
0を返します。 - 一致するすべての部分文字列を、それぞれの要素で構成された配列として保存することもできます。引数に割り当てる変数を指定するだけです。
- メールアドレス、URL、HTMLタグなどの特定のパターンの文字列を検証する際に有用です。
基本例
/* 文字列から
一致するすべての正規表現パターンの文字列を検索し、
その個数を整数で返します。 */
// 対象の文字列
$str = 'apple orange banana apple';
// 検索する正規表現パターン
$pattern = '/apple/';
// 関数を適用し結果を返す
$result = preg_match_all($pattern, $str);
var_dump($result); // 出力: int(2)
/* 一致するすべての部分文字列を
それぞれの要素で構成された配列として保存することもできます。
第3引数に割り当てる変数を指定します。 */
// 第3引数に割り当てる変数($matches)を指定
$result = preg_match_all($pattern, $str, $matches);
// 割り当てられた配列を確認
print_r($matches);
/* 出力:
Array
(
[0] => Array
(
[0] => apple
[1] => apple
)
)
*/
文字列内で正規表現を使用して特定のパターンを検索し、別の文字列に置換するには、preg_replace() 関数を使用してください。
構文
preg_match_all(
string $pattern,
string $subject,
array &$matches = null,
int $flags = 0,
int $offset = 0
): int|false
/* preg_match_all(
パターン,
検索対象となる文字列[,
一致した部分を保存する配列[,
追加の設定を指定するフラグ[,
検索を開始する文字列内のオフセット]]]
);
*/
引数
$pattern |
必須。検索する正規表現パターンです。 |
|---|---|
$subject |
必須。検索対象となる文字列です。 |
&$matches |
オプション。正規表現パターンに一致した結果を保存する配列です。
この配列は関数の呼び出し後に格納されます。(参照変数です。)
|
$flags |
オプション。マッチング結果の配列のソート方式を指定するフラグです。
この値を省略してソート関連のフラグを指定しない場合は、デフォルト値の 0 が指定され、PREG_PATTERN_ORDER 方式がデフォルトで適用されます。
以下のフラグを組み合わせて使用できます。
|
$offset |
オプション。検索を開始する文字列内のオフセットです。0 から始まります。この値を指定すると、文字列の該当するインデックス位置(バイト単位)から正規表現の検索が実行されます。 |
ご注意ください!
他の言語(例:JavaScript)では、全検索を行うために g (Global) フラグを使用してすべてのパターンマッチングを検索しますが(例:JavaScript の文字列 match() 関数)、PHP の正規表現に関連する PCRE 関数(例:preg_match(), preg_match_all())では g フラグを使用しません。
変更履歴
| バージョン | 説明 |
|---|---|
| 7.2.0 | $flags 引数の値として、PREG_UNMATCHED_AS_NULL フラグが使用できるようになりました。 |
戻り値
- 正規表現パターンに一致するすべての部分文字列を検索し、その個数を整数で返します。
- 一致するパターンが見つからない場合は、
0を返します。 - 一致した項目を格納した配列を、この関数の引数として渡した変数に割り当てます。
- エラーが発生した場合は
falseを返し、渡された正規表現パターンが有効でない場合はE_ERRORが発生します。
正規表現パターンに一致した結果と戻り値の例
一致するすべての部分の個数を返します。
preg_match_all() 関数は、対象の文字列から一致するすべての部分を検索します。戻り値は、一致した部分の総数となります。
$pattern = '/apple/';
$subject = "apple orange banana apple";
$result = preg_match_all($pattern, $subject);
if ($result !== false) {
var_dump($result); // 出力: int(2)
}
半面、この関数と類似した preg_match() 関数は、一致するパターンを文字列内で最初に見つけると検索を中断し、1 を返します。
一致するパターンが見つからない場合は 0 を返します。
一致するパターンが見つからない場合は 0 を返します。ここで注意すべき点は、false を返さないことです。false はエラーが発生した場合に返されます。
$pattern = '/grape/';
$subject = "apple orange banana apple";
$result = preg_match_all($pattern, $subject);
if ($result !== false) {
var_dump($result); // 出力: int(0)
}
エラーが発生した場合は false を返します。
error_reporting(0); // エラー表示の無効化
$pattern = '/apple'; // 無効な正規表現を使用
$subject = "apple orange banana apple";
$result = preg_match_all($pattern, $subject);
if ($result !== false) {
var_dump($result);
} else {
echo 'エラーが発生しました。';
}
// 出力: 'エラーが発生しました。'
一致した項目を格納した配列を、引数として渡した変数に割り当てます。
preg_match_all() を使用して、一致した項目を格納した配列を別の変数に割り当てるには、該当する配列を参照として渡します。
まず、例を通して見てみましょう。
// 与えられた文字列から数字を検索
$string = 'これは 123 と 456 を含むサンプルテキストです。';
// パターン:数字を検索
$pattern = '/\d+/';
// $matches という空の配列を宣言し、割り当てるための空間を用意します。
$matches = array();
// $matches を引数に割り当てます。
$num_of_matches = preg_match_all($pattern, $string, $matches);
// 結果の出力
if ($num_of_matches > 0) {
var_dump($matches); // array(1) { [0]=> array(2) { [0]=> string(3) "123" [1]=> string(3) "456" } }
}
ここで preg_match_all() 関数の第3引数として $matches 配列を渡しています。このとき、$matches 配列は関数呼び出し後に一致した部分文字列で満たされます。コードでは print_r($matches) を通じて配列の内容を出力しています。
これにより、$matches 配列に一致した項目が割り当てられ、関数の外部でもこの値を使用できるようになります。
正規表現にキャプチャグループがある場合の $flags と戻り値の例
preg_match_all() 関数は、単にすべてのマッチングを検索して返すだけでなく、引数で指定する $flags の値や、指定した正規表現におけるキャプチャグループの有無によって、結果の配列構造が大きく異なります。
以下は、指定する正規表現にキャプチャグループがある場合、$flags の値によって結果の配列が異なる例です。
PREG_PATTERN_ORDER
マッチング結果をパターンのキャプチャグループごとにソートします。$matches[0] にはパターン全体に一致した文字列が、$matches[1], $matches[2], … には各括弧のグループ(キャプチャグループ)に一致した文字列が配列として格納されます。キャプチャグループがない場合、$matches[0] 以外のインデックスは存在しません。
// 例の文字列
$string = "apple orange banana apple";
// 正規表現パターン: 'apple' または 'orange' を検索し、括弧のグループで囲む
$pattern = '/(apple|orange)/';
// PREG_PATTERN_ORDER を使用
// - マッチング結果をパターン(キャプチャグループ)ごとにソート
// - $matches : 結果を割り当てる配列変数
// - $matches[0] : パターン全体に一致した文字列
// - $matches[1] : 最初の括弧のグループ(キャプチャグループ)に一致した文字列
preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER);
// 結果の出力
print_r($matches);
/*
出力:
Array
(
[0] => Array ( [0] => apple [1] => orange [2] => apple )
[1] => Array ( [0] => apple [1] => orange [2] => apple )
)
*/
PREG_SET_ORDER
マッチングした結果を、1回ごとのマッチング単位でまとめてソートします。
各マッチング結果の配列の最初の要素 $matches[n][0] はパターン全体のマッチングであり、キャプチャグループがある場合は $matches[n][1], $matches[n][2] ... に各グループにマッチした文字列が入ります。キャプチャグループがない場合、$matches[n][1], $matches[n][2] ... は存在しません。
(PREG_PATTERN_ORDER と併用することはできません。)
// 例の文字列
$string = "apple orange banana apple";
// 正規表現パターン: 'apple' または 'orange' を検索し、括弧のグループで囲む
$pattern = '/(apple|orange)/';
// PREG_SET_ORDER を使用
// - マッチングした結果を1回ごとのマッチング単位でまとめてソート
// - $matches : 結果を割り当てる配列変数
// - $matches[0], $matches[1], … : それぞれ1回ごとのマッチング結果
preg_match_all($pattern, $string, $matches, PREG_SET_ORDER);
// 結果の出力
print_r($matches);
/*
出力:
Array
(
[0] => Array ( [0] => apple [1] => apple ) // 1回目のマッチング:全体 + 第1グループ
[1] => Array ( [0] => orange [1] => orange ) // 2回目のマッチング:全体 + 第1グループ
[2] => Array ( [0] => apple [1] => apple ) // 3回目のマッチング:全体 + 第1グループ
)
*/
PREG_OFFSET_CAPTURE
各マッチング結果に文字列の開始位置(オフセット)インデックスを併せて格納します。
この場合、$matches の各要素は [一致した文字列, 開始位置インデックス] という形式の配列になります。キャプチャグループがある場合は、各グループにも同様に [文字列, 開始位置] の配列が適用されます。
// 例の文字列
$string = "apple orange banana apple";
// 正規表現パターン: 'apple' または 'orange' を検索し、括弧のグループで囲む
$pattern = '/(apple|orange)/';
// PREG_OFFSET_CAPTURE を使用
// - 各マッチング結果に文字列の開始位置(オフセット)を併せて格納
// - $matches : 結果を割り当てる配列変数
// - $matches の各要素は [一致した文字列, 開始位置インデックス] の形式
preg_match_all($pattern, $string, $matches, PREG_OFFSET_CAPTURE);
// 結果の出力
print_r($matches);
/*
出力:
Array
(
[0] => Array (
[0] => Array("apple", 0) // パターン全体 1回目のマッチングと位置
[1] => Array("orange", 6) // パターン全体 2回目のマッチングと位置
[2] => Array("apple", 19) // パターン全体 3回目のマッチングと位置
)
[1] => Array (
[0] => Array("apple", 0) // 第1グループ 1回目のマッチングと位置
[1] => Array("orange", 6) // 第1グループ 2回目のマッチングと位置
[2] => Array("apple", 19) // 第1グループ 3回目のマッチングと位置
)
)
*/
PREG_UNMATCHED_AS_NULL
正規表現で一致しなかったサブパターン(subpattern)を null として処理します。このフラグを使用しない場合は、空の文字列('')として処理されます。キャプチャグループがない場合、このフラグは意味を持ちません。
// 例の文字列
$string = "apple banana";
// 正規表現パターン: 'apple', 'banana', 'orange' の3つのグループ
$pattern = '/(apple)|(banana)|(orange)/';
// PREG_UNMATCHED_AS_NULL を使用
// - 一致しなかったサブパターン(subpattern)を null として処理
// - $matches : 結果を割り当てる配列変数
// - $matches[0], $matches[1], ... 各グループのマッチングが null または文字列として格納される
preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER | PREG_UNMATCHED_AS_NULL);
// 結果の出力
print_r($matches);
/*
出力:
Array
(
[0] => Array ( [0] => apple [1] => banana ) // パターン全体のマッチング
[1] => Array ( [0] => apple [1] => null ) // 第1グループ: 'apple' のみマッチ
[2] => Array ( [0] => null [1] => banana ) // 第2グループ: 'banana' のみマッチ
[3] => Array ( [0] => null [1] => null ) // 第3グループ: 'orange' のマッチングなし → null
)
*/
活用例
preg_match_all() 関数は、メールアドレスや URL のような特定のパターンの文字列を検査する際に有用です。また、さまざまな状況で効果的に活用できます。ここでは、いくつかの例を扱います。
メールアドレスの検証
$string = 'お問い合わせは help@example.com または support@example.org までご連絡ください。';
$pattern = '/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/';
$matches = array();
$result = preg_match_all($pattern, $string, $matches);
if ($result !== false && $result > 0) {
print_r($matches[0]); // すべてのマッチしたメールアドレスを出力
echo "\n最初のメールアドレス: " . $matches[0][0]; // 最初のメールアドレスのみを出力
} else {
echo 'メールアドレスの形式が見つかりません。';
}
// 出力:
// Array ( [0] => help@example.com [1] => support@example.org )
// 最初のメールアドレス: help@example.com
URLの検証
$string = '詳細は https://www.example.com で確認してください。';
$pattern = '/\b(?:https?:\/\/)?(?:www\.)?[a-zA-Z0-9-]+(?:\.[a-z]{2,})+(?:\/[^\s]*)?\b/';
$matches = array();
$result = preg_match_all($pattern, $string, $matches);
if ($result !== false && $result > 0) {
echo $matches[0][0]; // 最初のマッチしたURLを出力
} else {
echo 'URLの形式が見つかりません。';
}
// 出力: 'https://www.example.com'
HTMLからタグを抽出
$html = '<div class="container"><p>Hello, <b>world!</b></p></div>';
$tagPattern = '/<[^>]+>/'; // HTMLタグを検索する正規表現
$matches = array();
$result = preg_match_all($tagPattern, $html, $matches);
if ($result !== false && $result > 0) {
print_r($matches[0]); // すべてのマッチしたタグを出力
} else {
echo 'タグが見つかりませんでした。';
}
// 出力:
// Array ( [0] => <div class="container"> [1] => <p> [2] => <b> [3] => </b> [4] => </p> [5] => </div> )
CSSクラスセレクタの抽出
$css = '.header { color: #333; } .main-content { font-size: 16px; }';
$classPattern = '/\.([a-zA-Z0-9_-]+)/'; // CSSクラスセレクタのパターン
$matches = array();
$result = preg_match_all($classPattern, $css, $matches);
if ($result !== false && $result > 0) {
print_r($matches[0]); // マッチしたクラスセレクタ全体を出力
} else {
echo 'CSSクラスセレクタが見つかりませんでした。';
}
// 出力:
// Array ( [0] => .header [1] => .main-content )