Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】RegexIterator::GET_MATCH定数の使い方

GET_MATCH定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

『GET_MATCH定数は、RegexIteratorクラスの動作モードを指定するための定数です。』RegexIteratorは、配列などの繰り返し可能なデータの中から、指定した正規表現にマッチする要素だけを抽出して処理するためのクラスです。このGET_MATCH定数をRegexIteratorのコンストラクタやsetFlagsメソッドでフラグとして設定すると、イテレータが返す値の形式が変更されます。具体的には、通常はマッチした要素のキーと値をそのまま返すのに対し、GET_MATCHを指定した場合は、正規表現にマッチした部分文字列の配列を返すようになります。この返される配列の構造は、PHPのpreg_match()関数がマッチ結果を格納する配列と同じ形式です。配列のインデックス0にはマッチした文字列全体が格納され、それ以降のインデックスには正規表現パターン内で丸括弧によってキャプチャされた各部分文字列が格納されます。この機能により、データの中から特定のパターンを抽出し、その抽出した文字列自体を直接利用する処理を簡潔に記述できます。

構文(syntax)

1<?php
2
3$data = new ArrayIterator(['test1', 'skip', 'test2']);
4
5$iterator = new RegexIterator(
6    $data,
7    '/test(\d)/',
8    RegexIterator::GET_MATCH
9);
10
11foreach ($iterator as $match) {
12    print_r($match);
13}
14
15?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

RegexIterator::GET_MATCHは、preg_match()関数のように、マッチした文字列全体を返します。

サンプルコード

PHP RegexIterator GET_MATCH でマッチ結果を取得する

1<?php
2
3/**
4 * RegexIterator::GET_MATCH 定数の使用例
5 *
6 * この関数は、文字列の配列から特定の正規表現にマッチする要素を抽出し、
7 * そのマッチ結果を詳細な配列形式で表示します。
8 * RegexIterator::GET_MATCH フラグは、マッチした要素全体だけでなく、
9 * 正規表現のキャプチャグループも含む配列として結果を返すよう指定します。
10 */
11function demonstrateRegexIteratorGetMatch(): void
12{
13    // 処理対象となる文字列のリスト
14    $dataItems = [
15        'item_id_123',
16        'product_code_A456B',
17        'user_score_78',
18        'order_ref_91011',
19        'no_match_here', // この要素は正規表現にマッチしない
20    ];
21
22    // ArrayIterator を使用して配列をイテレータに変換します。
23    // RegexIterator は Iterator インターフェースを実装したオブジェクトを引数に取ります。
24    $arrayIterator = new ArrayIterator($dataItems);
25
26    // RegexIterator を初期化します。
27    // 第1引数: ベースとなるイテレータ ($arrayIterator)
28    // 第2引数: マッチさせたい正規表現パターン。ここでは「_」の後に続く数字にマッチし、数字部分をキャプチャします。
29    // 第3引数: フィルタリングのモード。RegexIterator::MATCH は、正規表現にマッチする要素のみを返します。
30    // 第4引数: 結果の形式を制御するフラグ。RegexIterator::GET_MATCH を指定すると、
31    //          イテレータはマッチした要素の「配列」を返します。この配列には、
32    //          全体のマッチ文字列と、正規表現のキャプチャグループが含まれます。
33    $regexIterator = new RegexIterator(
34        $arrayIterator,
35        '/_(\d+)/', // アンダーバーの後に続く1つ以上の数字にマッチし、数字部分をキャプチャ
36        RegexIterator::MATCH,
37        RegexIterator::GET_MATCH
38    );
39
40    echo "RegexIterator::GET_MATCH を使用したマッチ結果:\n";
41    echo "-------------------------------------------\n";
42
43    // イテレータをループし、結果を表示します。
44    // 各 $match は配列であり、以下のような形式になります:
45    // $match[0] => 正規表現全体がマッチした文字列 (例: "_123")
46    // $match[1] => 1番目のキャプチャグループにマッチした文字列(ここでは数字部分、例: "123")
47    foreach ($regexIterator as $originalKey => $match) {
48        echo "元のキー: {$originalKey}\n";
49        echo "マッチ結果:\n";
50        print_r($match); // 配列の内容を表示
51        echo "-------------------------------------------\n";
52    }
53}
54
55// 関数の実行
56demonstrateRegexIteratorGetMatch();

PHP 8のRegexIteratorクラスに属するGET_MATCH定数は、正規表現を用いたフィルタリング処理において、マッチした結果をどのような形式で返すかを制御するための定数です。この定数自体は引数を取らず、整数値(int)を返します。

通常、RegexIteratorは正規表現にマッチした元の要素をそのまま返しますが、RegexIterator::GET_MATCHフラグを指定すると、イテレータは元の要素ではなく、正規表現のマッチ結果を詳細な配列形式で返します。この配列には、正規表現全体がマッチした文字列が最初の要素(インデックス0)として含まれるほか、正規表現で定義されたキャプチャグループにマッチした文字列も含まれます。

サンプルコードでは、文字列の配列から「_の後に続く1つ以上の数字」というパターンにマッチする要素を抽出し、GET_MATCH定数を用いてそのマッチ結果を配列として取得しています。例えば、「item_id_123」という文字列がこのパターンにマッチした場合、GET_MATCHを指定することで、全体のマッチ文字列である「_123」と、キャプチャグループで指定された数字部分「123」の両方を配列として受け取ることができます。このように、マッチしたデータ全体だけでなく、その中の特定の情報を効率的に抽出できるため、複雑なデータ処理やパース処理を行う際に非常に有用です。

このサンプルコードの注意点として、RegexIterator::GET_MATCHを使用すると、foreachループで取得する値が、マッチした文字列そのものではなく、全体のマッチとキャプチャグループを含む「配列」となる点に特に注意が必要です。この配列では、$match[0]が正規表現全体のマッチ部分を、$match[1]以降が各キャプチャグループのマッチ内容を示しますので、アクセスする際の添字を正しく理解してください。また、第三引数でフィルタリングモード(例:RegexIterator::MATCH)を、第四引数で結果の形式を制御するフラグ(例:RegexIterator::GET_MATCH)をそれぞれ適切に指定することが、意図した動作を得るために重要です。この定数は、正規表現による詳細なマッチ結果を効率的に取得したい場合に大変便利に利用できます。

PHP RegexIterator GET_MATCH で全件検索

1<?php
2
3/**
4 * Demonstrates the use of RegexIterator with RegexIterator::GET_MATCH
5 * to extract the first regex match from each qualifying string in a collection.
6 *
7 * This function processes an array of strings. For each string that contains
8 * at least one match for the given regular expression pattern, it extracts
9 * the *first* full match and any captured groups. This allows you to
10 * efficiently get "all first matches" from an iterable collection of data.
11 *
12 * While the keyword "get all matches" might sometimes imply finding all occurrences
13 * within a *single* string (which is typically done with `preg_match_all`),
14 * `RegexIterator::GET_MATCH` specifically returns the result of the *first*
15 * match found for each element in the underlying iterator.
16 *
17 * @param array<string> $inputStrings An array of strings to search within.
18 * @param string $pattern The regular expression pattern to search for.
19 * @return array<array<int, string>> An array of match results. Each inner array
20 *                                   represents the first match found in one of the
21 *                                   input strings, containing the full match (index 0)
22 *                                   and any captured groups (index 1, 2, ...).
23 */
24function findAllFirstRegexMatchesInStrings(array $inputStrings, string $pattern): array
25{
26    // 1. Create an ArrayIterator from the input strings.
27    //    RegexIterator requires an object that implements the Iterator interface
28    //    (or Traversable) as its data source. ArrayIterator is suitable for arrays.
29    $arrayIterator = new ArrayIterator($inputStrings);
30
31    // 2. Create a RegexIterator instance.
32    //    - First argument: The iterator to filter/transform (our ArrayIterator).
33    //    - Second argument: The regular expression pattern to apply.
34    //    - Third argument: RegexIterator::GET_MATCH. This constant determines
35    //      the iteration mode. In GET_MATCH mode, for each element from the
36    //      $arrayIterator that matches the $pattern, the RegexIterator yields
37    //      an array containing the *first* full match and its captured subgroups.
38    //      This is similar to the output format of `preg_match()` (not `preg_match_all()`)
39    //      when a match is found.
40    $regexIterator = new RegexIterator($arrayIterator, $pattern, RegexIterator::GET_MATCH);
41
42    $allCollectedMatches = [];
43
44    // 3. Iterate over the RegexIterator to retrieve the results.
45    //    For each iteration, $key will be the original index from $arrayIterator
46    //    where a match was found.
47    //    $matchResult will be an array, e.g., `['matched_substring', 'group1', 'group2']`.
48    echo "--- Processing Strings for First Matches ---\n";
49    foreach ($regexIterator as $originalKey => $matchResult) {
50        // Output for beginner understanding:
51        echo "  String at original index '{$originalKey}' matched.\n";
52        echo "    Full first match: '{$matchResult[0]}'\n";
53        if (count($matchResult) > 1) {
54            // If the pattern has capturing groups, they will be in $matchResult[1], $matchResult[2], etc.
55            echo "    Captured group(s): " . implode(', ', array_slice($matchResult, 1)) . "\n";
56        }
57        $allCollectedMatches[] = $matchResult;
58    }
59    echo "--- Finished Processing ---\n\n";
60
61    return $allCollectedMatches;
62}
63
64// --- Example Usage ---
65
66// Define a collection of strings to search within.
67$dataStrings = [
68    "Order #101: 5 items, total $125.50.",
69    "No numbers or specific codes here.",
70    "Another order #202 with 2 items, total $30.00.",
71    "Product ID: P456. Quantity: 3. Price: $10.99 and a second number 20.00.",
72    "Empty string.",
73];
74
75// Define a regular expression pattern.
76// This pattern captures one or more digits (\d+) and potentially a decimal part (.\d+).
77// The outer parentheses create a capturing group around the entire number.
78$numberPattern = '/(\d+(\.\d+)?)/';
79
80echo "Input Data:\n";
81foreach ($dataStrings as $index => $str) {
82    echo "  [{$index}]: \"{$str}\"\n";
83}
84echo "\n";
85
86// Call the function to find all first matches using RegexIterator::GET_MATCH.
87$results = findAllFirstRegexMatchesInStrings($dataStrings, $numberPattern);
88
89// Display the collected first matches.
90echo "--- Summary of All First Matches Found ---\n";
91if (!empty($results)) {
92    foreach ($results as $idx => $matchArray) {
93        echo "Match " . ($idx + 1) . ":\n";
94        echo "  Full match (index 0): '{$matchArray[0]}'\n";
95        if (isset($matchArray[1])) {
96            // In our $numberPattern, group 1 captures the entire number including decimal.
97            echo "  Group 1 (the number itself): '{$matchArray[1]}'\n";
98        }
99        if (isset($matchArray[2])) {
100            // Group 2 captures the optional decimal part.
101            echo "  Group 2 (optional decimal part): '{$matchArray[2]}'\n";
102        }
103    }
104} else {
105    echo "No matches were found across the collection of strings.\n";
106}
107
108?>

PHPのRegexIterator::GET_MATCHは、RegexIteratorクラスで、データの中から正規表現にマッチする部分をどのように抽出するかを指定する定数です。この定数を使用すると、RegexIteratorは元のデータ(イテレータ)の各要素を一つずつ調べ、正規表現パターンに合致する部分があれば、その要素から見つかった「最初のマッチ」を配列として返します。これは、特定のデータ構造の中から、条件に合う情報だけを効率的に取り出したい場合に利用されます。

サンプルコードでは、複数の文字列が格納された配列から、正規表現を使って「最初の数値」を抽出しています。具体的には、まず文字列配列をArrayIteratorで包み、次にこのArrayIteratorと正規表現パターン、そしてRegexIterator::GET_MATCH定数を指定してRegexIteratorを作成します。その後、このRegexIteratorforeachループで処理すると、パターンにマッチした各文字列から、見つかった「最初のマッチ」が配列として取得できます。この配列の戻り値は、マッチした部分全体の文字列(インデックス0)と、正規表現で定義されたキャプチャグループの各要素(インデックス1以降)で構成されます。これにより、複数のデータから必要な情報を簡潔に抽出することが可能です。

RegexIterator::GET_MATCHモードは、入力された各文字列に対して正規表現パターンを適用し、最初に見つかった1つのマッチ結果のみを返します。これは、1つの文字列内から全てのマッチを抽出するpreg_match_all関数とは異なる動作ですので、混同しないよう注意が必要です。戻り値の配列では、インデックス0に全体のマッチが、1以降に正規表現で定義されたキャプチャグループの内容が格納されます。マッチしなかった入力文字列は結果から除外されます。正規表現の記述は結果に大きく影響するため、目的のパターンを正確に表現し、意図通りの結果が得られるか十分に確認してください。大量のデータを扱う際には、パフォーマンスも考慮した正規表現の設計が重要です。

関連コンテンツ