PHP で正規表現を使って分割するには preg_split を使うのだけれど分割する時にマッチした部分も返したい場合は第4引数に PREG_SPLIT_DELIM_CAPTURE を設定する

preg_split で分割する場合に第4引数に PREG_SPLIT_DELIM_CAPTURE を設定するとマッチさせた部分の括弧内にあるテキストも取得することができます。
PHP: preg_split – Manual

例えば以下のように格納されたテキストデータを処理する場合。

1
2
3
4
5
6
7
8
9
10
11
[テキスト]
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
 
[テキスト]
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。

以下のような普通のコードを書いてしまうと。

1
2
3
$contents_data = preg_split("/\[(.*?)\]/", $contents, null);
array_splice($contents_data, 0, 1);
print_r($contents_data);

以下のような配列しか取得できませんが。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array
(
    [0] => 
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
 
 
    [1] => 
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
)

以下のように第4引数に PREG_SPLIT_DELIM_CAPTURE を与えてあげると。

1
2
3
$contents_data = preg_split("/\[(.*?)\]/", $contents, null,  PREG_SPLIT_DELIM_CAPTURE);
array_splice($contents_data, 0, 1);
print_r($contents_data);

以下のようにマッチした部分も取り出すことができます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Array
(
    [0] => テキスト
    [1] => 
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
 
 
    [2] => テキスト
    [3] => 
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
ここはテストのテキストになります。
)

凄く便利なので覚えておきたくてメモしておきました。

あと、array_splice は空配列になるだろう部分を排除しているだけですが、実際は PREG_SPLIT_NO_EMPTY を設定すれば空は抜かしてくれます。PREG_SPLIT_NO_EMPTY も第4引数に入れるのですが、ビット和演算子を使えば複数設定することができます。

1
2
$contents_data = preg_split("/\[(.*?)\]/", $contents, null,  PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
print_r($contents_data);

私の場合は括弧で見出しの次はテキストという一連の流れが決まっており、これが空の場合もあるということで、あえて一番先頭だけを削除している感じです。

コメント

コメントは受け付けていません。