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

【PHP8.x】PREG_OFFSET_CAPTURE定数の使い方

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

作成日: 更新日:

基本的な使い方

PREG_OFFSET_CAPTURE定数は、PHPの正規表現関数(preg_matchpreg_match_allなど)において、検索結果に追加情報を含めるかどうかを指定するためのオプションを表す定数です。この定数を正規表現関数のフラグとして指定することで、パターンにマッチした部分文字列だけでなく、その部分文字列が元の入力文字列のどこから開始しているかを示すオフセット位置(バイト単位)も同時に取得できるようになります。

具体的には、preg_match関数などでこの定数を指定すると、通常マッチした文字列が格納される結果配列の各要素が、マッチした文字列そのものと、その文字列の開始位置を示す数値の2つの要素を持つ配列の形式で返されます。例えば、「Hello World」という文字列から「World」を検索し、PREG_OFFSET_CAPTUREを指定した場合、結果には「World」という文字列と、それが元の文字列の「6」文字目から始まるという情報(オフセット)が含まれることになります。

この機能は、単に特定のパターンにマッチした文字列を見つけるだけでなく、そのマッチした部分が元の文字列のどの位置にあるかを正確に把握したい場合に非常に有用です。例えば、マッチした部分を別の文字列に置き換える際にその位置情報を使ったり、文字列の一部を切り出したりするような、より複雑な文字列操作を行う際の基準として利用できます。この定数を指定しない場合、返されるのはマッチした文字列のみとなり、オフセット情報は提供されません。そのため、文字列内での精密な位置特定が必要な場面で、PREG_OFFSET_CAPTURE定数は不可欠な役割を果たします。

構文(syntax)

1<?php
2$subject = "string to search";
3$pattern = '/(string) (to) (search)/';
4preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
5?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

戻り値なし

戻り値はありません

サンプルコード

PHP preg_match でオフセットを取得する

1<?php
2
3/**
4 * PREG_OFFSET_CAPTURE 定数を用いた正規表現マッチングの例を示します。
5 *
6 * PREG_OFFSET_CAPTURE を指定すると、マッチした文字列だけでなく、
7 * その文字列が元の文字列のどこから始まったかのオフセット(位置)も結果に含まれます。
8 */
9function demonstratePregOffsetCapture(): void
10{
11    $subject = "PHP is a popular scripting language.";
12    $pattern = "/language/"; // 検索するパターン
13
14    $matchesWithoutOffset = [];
15    $matchesWithOffset = [];
16
17    // --- PREG_OFFSET_CAPTURE を使用しない場合 ---
18    echo "--- PREG_OFFSET_CAPTURE なしの場合 ---\n";
19    // 戻り値はマッチした文字列のみを含む
20    if (preg_match($pattern, $subject, $matchesWithoutOffset)) {
21        echo "マッチ結果:\n";
22        print_r($matchesWithoutOffset);
23        // 出力例:
24        // Array
25        // (
26        //     [0] => language
27        // )
28    } else {
29        echo "マッチしませんでした。\n";
30    }
31    echo "\n";
32
33    // --- PREG_OFFSET_CAPTURE を使用する場合 ---
34    echo "--- PREG_OFFSET_CAPTURE ありの場合 ---\n";
35    // マッチした文字列と、その文字列が元の文字列内で開始したオフセット(位置)を含む
36    if (preg_match($pattern, $subject, $matchesWithOffset, PREG_OFFSET_CAPTURE)) {
37        echo "マッチ結果:\n";
38        print_r($matchesWithOffset);
39        // 出力例:
40        // Array
41        // (
42        //     [0] => Array
43        //         (
44        //             [0] => language  // マッチした文字列
45        //             [1] => 26      // 開始オフセット (0から始まる)
46        //         )
47        // )
48    } else {
49        echo "マッチしませんでした。\n";
50    }
51}
52
53// 関数を実行して動作を確認します
54demonstratePregOffsetCapture();
55

PHPのPREG_OFFSET_CAPTUREは、正規表現マッチングを行う際に、マッチした文字列だけでなく、その文字列が元のテキストのどこから始まったかを示す位置情報(オフセット)も取得するための定数です。主にpreg_matchなどの正規表現関数と組み合わせて使用されます。

この定数を正規表現関数のオプションとして指定しない場合、関数はマッチした部分文字列のみを結果として返します。例えば、「PHP is a popular scripting language.」という文字列から「language」を検索した場合、マッチ結果は「language」という文字列のみを含みます。

しかし、PREG_OFFSET_CAPTUREを指定すると、関数の戻り値であるマッチ結果の配列の構造が変化します。結果には、マッチした文字列そのものに加え、その文字列が元のテキストの先頭から何文字目で開始したかを示す数値(オフセット)が追加されます。これにより、マッチした部分が元の文字列のどの位置にあるかをプログラムで正確に把握できるようになります。

この定数自体に引数はなく、特定の値を返すわけではありませんが、正規表現関数のオプション引数として渡されることで、その関数の戻り値の挙動を細かく制御する重要な役割を担っています。サンプルコードでは、この定数の有無によってpreg_match関数の結果がどのように変わるかが具体的に示されています。

PREG_OFFSET_CAPTURE定数をpreg_match関数で使用すると、マッチ結果の配列構造が大きく変わる点に特に注意が必要です。この定数を指定しない場合、結果配列にはマッチした文字列のみが含まれますが、指定した場合は、マッチした文字列と、それが元の文字列のどこから始まったかのオフセット(位置)がセットで、さらに深い配列として格納されます。オフセットは文字列の先頭から数えて0から始まるため、値を取り出す際は配列のインデックスを誤らないよう注意してください。この機能は、単に文字列がマッチしたかどうかだけでなく、その位置情報も必要となる場面で非常に有用です。しかし、配列の構造が複雑になるため、初心者の方は値の取り出し方で間違いやすいポイントです。正しく利用するために、返される配列の構造をしっかり理解し、目的のデータにアクセスする際は配列の深さを考慮してください。これはpreg_match_allなど他の正規表現関数でも同様に適用されます。

関連コンテンツ