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

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

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

作成日: 更新日:

基本的な使い方

GET_MATCH定数は、RecursiveRegexIteratorクラスの動作モードを指定するための定数です。この定数をコンストラクタに設定することで、イテレータが返す値の形式を制御できます。通常、RecursiveRegexIteratorは正規表現にマッチしたイテレータの現在の要素、例えばファイル情報を表すSplFileInfoオブジェクトなどをそのまま返します。しかし、コンストラクタの第二引数であるモードにRecursiveRegexIterator::GET_MATCHを指定すると、イテレータは要素そのものではなく、正規表現にマッチした部分文字列を配列として返すようになります。この配列は、preg_match()関数でマッチ結果を取得したときと同じ構造を持ち、インデックス0にはマッチした文字列全体が、インデックス1以降には正規表現パターン内のキャプチャグループ(括弧で囲まれた部分)にマッチした文字列が格納されます。この機能は、ファイル名から日付やバージョン番号といった特定のパターンを抽出し、その抽出した文字列だけを直接処理したい場合に非常に便利です。要素全体を取得してから文字列を抽出する手間を省き、コードをより簡潔に記述することが可能になります。

構文(syntax)

1<?php
2
3$arrayIterator = new RecursiveArrayIterator([
4    'product-101',
5    'item-202',
6    'category' => [
7        'sub-item-303'
8    ]
9]);
10
11$regexIterator = new RecursiveRegexIterator(
12    $arrayIterator,
13    '/(\d+)/',
14    RecursiveRegexIterator::GET_MATCH
15);
16
17foreach ($regexIterator as $key => $value) {
18    // $keyにはマッチした文字列全体が、
19    // $valueにはpreg_match()の結果と同様の配列が格納されます。
20    var_dump([$key => $value]);
21}
22
23?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

RecursiveRegexIterator::GET_MATCH は、RecursiveRegexIterator::getMode() メソッドによって返される整数値であり、RecursiveRegexIterator::RECURSIVE モードが指定されている場合に、正規表現にマッチした部分文字列全体を返します。

サンプルコード

PHP GET_MATCH で正規表現マッチを取得する

1<?php
2
3// RecursiveRegexIterator::GET_MATCH 定数の使用例
4
5// この定数は RecursiveRegexIterator クラスで使用され、
6// 正規表現にマッチした要素について、そのマッチ結果(通常 preg_match で得られる配列)を返します。
7// システムエンジニア初心者の皆さんにとって、再帰的なデータ構造から特定のパターンに
8// 合致する情報を効率的に抽出する際に役立つ概念です。
9
10// 再帰的なデータ構造(多次元配列)を準備します。
11// RecursiveRegexIterator は RecursiveIterator を実装するオブジェクトと組み合わせて使用されます。
12$data = [
13    'products' => [
14        'fruits' => [
15            'apple' => 'red',
16            'banana' => 'yellow',
17            'grape' => 'purple',
18        ],
19        'vegetables' => [
20            'carrot' => 'orange',
21            'broccoli' => 'green',
22        ],
23    ],
24    'categories' => [
25        'food_item' => 'general',
26        'beverage' => 'drink',
27        'snack_item' => 'light',
28    ],
29    'metadata' => [
30        'version' => '1.0',
31    ],
32];
33
34// 1. RecursiveArrayIterator を使用して、この多次元配列をイテレータとして扱えるようにします。
35//    これにより、配列の各要素にアクセスできるようになります。
36$arrayIterator = new RecursiveArrayIterator($data);
37
38// 2. RecursiveRegexIterator を使用して、上記のイテレータを正規表現でフィルタリングします。
39//    第2引数に正規表現、第3引数にフィルタリングモードを指定します。
40//    RecursiveRegexIterator::GET_MATCH モードは、マッチした要素(キー)について、
41//    その元の値ではなく、正規表現のマッチ結果を配列として返します。
42//    この例では、キーが "item" で終わるもの、または "banana" に完全に一致するものを探します。
43$regexIterator = new RecursiveRegexIterator(
44    $arrayIterator,
45    '/^(.*item|banana)$/i', // 正規表現: "item" で終わる、または "banana" に完全に一致するキー (大文字小文字を区別しない)
46    RecursiveRegexIterator::GET_MATCH // マッチ結果の配列を返すモード
47);
48
49// 3. RecursiveIteratorIterator を使用して、RecursiveRegexIterator が返す再帰的な構造を
50//    フラット化して処理できるようにします。これにより、ネストされた要素も一度にループできます。
51$iterator = new RecursiveIteratorIterator($regexIterator);
52
53echo "RecursiveRegexIterator::GET_MATCH モードでの出力結果:\n";
54echo "---------------------------------------------------\n";
55
56// イテレータをループして結果を出力します。
57foreach ($iterator as $key => $matchResultArray) {
58    // $key は元のデータ構造におけるマッチした要素のキーです。
59    // $matchResultArray は RecursiveRegexIterator::GET_MATCH モードによって返される配列です。
60    // この配列は PHP の preg_match 関数が返す結果と同様に、
61    // 最初の要素が全体のマッチ、後続の要素が正規表現内のキャプチャグループのマッチを含みます。
62
63    echo "マッチしたキー: " . $key . "\n";
64    echo "マッチ結果の配列:\n";
65    print_r($matchResultArray);
66    echo "---------------------------------------------------\n";
67}
68
69?>

RecursiveRegexIterator::GET_MATCH定数は、PHPのRecursiveRegexIteratorクラスで使用されるモード指定のための定数です。この定数には引数がなく、整数値が返されます。主な役割は、正規表現にマッチした要素に対して、単にマッチしたキーや値を返すのではなく、正規表現のマッチ結果そのものを詳細な配列として取得することです。

システムエンジニアを目指す初心者の方にとって、この定数は再帰的なデータ構造の中から特定のパターンに合致する情報を、より詳細な形で抽出したい場合に役立ちます。具体的には、この定数をRecursiveRegexIteratorの第3引数(mode)に指定すると、イテレータを反復した際に、各要素の元のキーと共に、PHPのpreg_match関数が返すような、正規表現のマッチ結果(全体のマッチやキャプチャグループを含む配列)が返されます。

サンプルコードでは、まず多次元配列をRecursiveArrayIteratorでイテレータとして扱えるようにしています。次に、RecursiveRegexIteratorをこれに適用し、キーが"item"で終わるか"banana"に完全に一致するパターンを検索しています。ここでRecursiveRegexIterator::GET_MATCHモードを指定することで、ループ処理時に取得される値は、マッチしたキーに対応する元のデータではなく、正規表現のキャプチャグループなどを含むマッチ結果の配列となります。これにより、例えば「banana」というキーが見つかった場合、そのキーと「banana」というマッチ結果の配列が得られるといった具体的な挙動を確認できます。このように、マッチした部分の具体的な情報をプログラムで活用する際に非常に便利な機能です。

RecursiveRegexIterator::GET_MATCHは、正規表現にマッチした要素そのものを直接取得するのではなく、マッチした内容に関する詳細な情報を配列として返します。この配列には、正規表現の全体のマッチや、括弧で指定したキャプチャグループのマッチ結果が含まれるため、目的に応じて配列から適切な値を取り出す必要があります。サンプルコードでは、複数のイテレータを組み合わせて利用していますが、RecursiveArrayIteratorは配列の反復、RecursiveRegexIteratorは正規表現によるフィルタリング、RecursiveIteratorIteratorは再帰的な構造を処理するための役割を持っています。それぞれのイテレータの機能を理解することが、複雑なデータから効率的に情報を抽出するために非常に重要です。

PHPで正規表現の全マッチを取得する

1<?php
2
3/**
4 * RecursiveRegexIterator と RecursiveRegexIterator::GET_MATCH 定数を使用して、
5 * 配列内の各文字列から正規表現にマッチするすべての部分文字列を取得する関数。
6 *
7 * RecursiveRegexIterator::GET_MATCH 定数は、マッチした部分文字列全体を返すように動作を制御します。
8 * RecursiveRegexIterator::ALL_MATCHES 定数と組み合わせることで、各要素から複数のマッチを抽出できます。
9 *
10 * @param array $data 検索対象の文字列を含む配列。
11 * @param string $pattern 検索に使用する正規表現パターン。
12 * @return array マッチした結果を格納した配列。キーは元の配列のキーに対応し、値はマッチした部分文字列の配列です。
13 */
14function findAllRegexMatchesInArray(array $data, string $pattern): array
15{
16    // 検索対象の配列をRecursiveArrayIteratorでラップします。
17    // RecursiveRegexIteratorはRecursiveIteratorインターフェースを実装したイテレータを必要とします。
18    $arrayIterator = new RecursiveArrayIterator($data);
19
20    // RecursiveRegexIteratorを作成します。
21    // 第2引数: 正規表現パターン
22    // 第3引数: フラグ
23    //   - RecursiveRegexIterator::GET_MATCH: マッチした部分文字列全体を返すように指定します。
24    //   - RecursiveRegexIterator::ALL_MATCHES: 各要素内で見つかったすべてのマッチを配列で返すように指定します。
25    //   これらをビットOR演算子 (|) で結合することで、両方の動作が適用されます。
26    $regexIterator = new RecursiveRegexIterator(
27        $arrayIterator,
28        $pattern,
29        RecursiveRegexIterator::GET_MATCH | RecursiveRegexIterator::ALL_MATCHES
30    );
31
32    $results = [];
33
34    // イテレータをループして、正規表現にマッチした結果を取得します。
35    // $key は元の配列のキー、 $matches はマッチした部分文字列の配列になります。
36    foreach ($regexIterator as $key => $matches) {
37        $results[$key] = $matches;
38    }
39
40    return $results;
41}
42
43// --- サンプルコードの実行例 ---
44
45// 検索対象の文字列データ
46$sampleData = [
47    'Apple pie and banana bread',
48    'Orange juice is rich in vitamin C',
49    'Pineapple pizza is controversial',
50    'No fruit here, just text'
51];
52
53// 検索したい正規表現パターン (例: 'apple' または 'orange' に大文字小文字を区別せずマッチ)
54$searchPattern = '/(apple|orange)/i';
55
56// 関数を呼び出して、配列内のすべての正規表現マッチを取得します。
57$foundMatches = findAllRegexMatchesInArray($sampleData, $searchPattern);
58
59// 結果の出力
60echo "--- Original Data ---\n";
61print_r($sampleData);
62echo "\n--- Found Matches ---\n";
63print_r($foundMatches);
64
65?>

PHP 8のRecursiveRegexIteratorクラスに定義されているGET_MATCH定数は、正規表現による検索結果の取得方法を制御するために使用されます。この定数は、RecursiveRegexIteratorが正規表現にマッチした際、そのマッチした部分文字列「全体」を結果として返すように指定する役割を持ちます。戻り値は整数型であり、他の定数とビットOR演算子で組み合わせて、さらに詳細な動作を設定することができます。

サンプルコードのfindAllRegexMatchesInArray関数は、このGET_MATCH定数とRecursiveRegexIterator::ALL_MATCHES定数を活用し、入力された配列内の各文字列から正規表現にマッチするすべての部分文字列を効率的に抽出します。具体的には、まず検索対象の配列をRecursiveArrayIteratorでラップし、それをRecursiveRegexIteratorに渡します。RecursiveRegexIteratorのコンストラクタで、正規表現パターンと共にRecursiveRegexIterator::GET_MATCHRecursiveRegexIterator::ALL_MATCHESを結合したフラグを指定します。これにより、各要素から複数のマッチがそれぞれ配列として取得され、その配列にはマッチした部分文字列全体が格納されます。

関数は、検索対象の文字列を含む配列$dataと、検索に使用する正規表現パターン$patternを引数として受け取ります。そして、処理された結果として、元の配列のキーに対応する形で、見つかったすべてのマッチを格納した配列を返します。これにより、複雑な正規表現検索と結果の整形を簡潔に行うことが可能です。

このサンプルコードは、配列内の各文字列から正規表現にマッチするすべての部分文字列を効率的に取得する方法を示しています。RecursiveRegexIterator::GET_MATCH定数は、マッチした部分文字列全体を返すように動作を制御し、RecursiveRegexIterator::ALL_MATCHESと組み合わせることで、各要素から複数のマッチを抽出できます。この二つの定数をビットOR演算子で結合している点が重要です。正規表現パターンは正しくデリミタで囲み、構文エラーがないように注意してください。また、非常に大きな配列や複雑な正規表現を使用する場合、処理性能に影響が出る可能性があります。このイテレータはメモリ効率が良いですが、適用するデータの規模を考慮するとより安全です。返される結果は、元の配列のキーに対応したマッチ文字列の配列となりますので、その構造を理解しておくと利用がスムーズになります。

関連コンテンツ