【PHP】preg_splitで文字列を分割する方法|explodeとの使い分け・フラグ・多バイト

PHPで文字列を分割して配列にするには、パターンで分割する preg_split()固定の区切り文字で分割する explode() があります。正規表現が必要なときは preg_split() が便利です。この記事では使い方と、explodeとの使い分けまで解説します。

この記事の結論:preg_split($pattern, $str)正規表現で分割します。「カンマ+空白」など複数パターンの区切りに便利です。区切りが単一の固定文字なら explode() の方が速く明快です。空要素を除くなら PREG_SPLIT_NO_EMPTY フラグを使います。
スポンサーリンク

preg_splitの基本

第1引数に正規表現、第2引数に対象文字列を渡します。パターンにマッチした箇所で分割し、配列を返します。

カンマ+空白で分割
<?php
$text = "apple, orange,banana ,grape";
// カンマの前後の空白も一緒に区切る
$result = preg_split('/\s*,\s*/', $text);
print_r($result);
// ["apple", "orange", "banana", "grape"]

explodeとの使い分け

区切りが単一の固定文字列(カンマだけ、改行だけ等)なら、正規表現を使わない explode() の方がシンプルで高速です。パターン(複数の区切り、空白の揺れ、正規表現)が必要なときに preg_split() を使います。

explode と preg_split
<?php
// 区切りが固定なら explode(速い・明快)
print_r(explode(",", "a,b,c")); // ["a", "b", "c"]

// 区切りにパターン(複数の区切り文字)が必要なら preg_split
print_r(preg_split('/[,;\s]+/', "a, b; c   d")); // ["a", "b", "c", "d"]
explode は「文字列をそのまま区切る」、preg_split は「正規表現パターンで区切る」と覚えると使い分けやすいです。逆に分割した配列を1つにまとめるのは配列を文字列に変換する方法(implode)を参照してください。

分割数を制限する(limit)

第3引数 limit で分割回数を制限できます。残りは分割されずに最後の要素にまとまります。

limitで分割回数を制限
<?php
$text = "one, two, three, four";
$result = preg_split('/,\s*/', $text, 2);
print_r($result);
// ["one", "two, three, four"]

フラグで挙動を変える

第4引数のフラグで、空要素の除去や区切り文字の取り込みができます。

PREG_SPLIT_NO_EMPTY / DELIM_CAPTURE
<?php
// 連続区切りで生じる空要素を除く
print_r(preg_split('/,/', "a,,b,", -1, PREG_SPLIT_NO_EMPTY));
// ["a", "b"]

// 区切り文字も結果に含める(() でキャプチャ + DELIM_CAPTURE)
print_r(preg_split('/(\d)/', "a1b2c", -1, PREG_SPLIT_DELIM_CAPTURE));
// ["a", "1", "b", "2", "c"]

日本語・1文字ずつの分割

日本語などマルチバイト文字を含むパターンで分割するときは、/u(UTF-8)修飾子を付けます。また「1文字ずつ配列にする」なら、英数字は str_split()、日本語は mb_str_split() を使います。

多バイト対応と1文字分割
<?php
// 日本語を含むパターンは /u を付ける
print_r(preg_split('/、\s*/u', "りんご、みかん、ぶどう"));
// ["りんご", "みかん", "ぶどう"]

// 1文字ずつ配列に(日本語は mb_str_split)
print_r(mb_str_split("あいう")); // ["あ", "い", "う"]
print_r(str_split("abc"));       // ["a", "b", "c"](英数字向き)
str_split()バイト単位で分割するため、日本語に使うと文字化けします。多バイト文字を1文字ずつ分けるならmb_str_split()(PHP 7.4+)を使ってください。

よくある質問(FAQ)

Qexplodeとpreg_splitはどちらを使うべきですか?
A区切りが単一の固定文字列なら explode()(速い・明快)、複数の区切りや空白の揺れなどパターンが必要なら preg_split() です。正規表現が不要なら explode を選ぶ方が効率的です。
Q連続した区切りで空の要素ができます。
A第4引数に PREG_SPLIT_NO_EMPTY を指定すると空要素を除けます。preg_split($pattern, $str, -1, PREG_SPLIT_NO_EMPTY) のように使います。
Q日本語の文字列がうまく分割できません。
Aパターンに /u 修飾子を付けてUTF-8として扱ってください。1文字ずつ分けたい場合は str_split()(バイト単位で化ける)ではなくmb_str_split() を使います。
Q区切り文字も結果に残したいです。
Aパターンを () でキャプチャし、フラグにPREG_SPLIT_DELIM_CAPTURE を指定します。区切りに使った文字も配列の要素として含まれます。

まとめ

preg_splitのポイントを整理します。

  • preg_split($pattern, $str)正規表現で分割
  • 固定の区切りなら explode() の方が速く明快
  • 空要素除去は PREG_SPLIT_NO_EMPTY、区切り保持は PREG_SPLIT_DELIM_CAPTURE
  • 日本語は /u。1文字分割は mb_str_split()(str_splitは化ける)

関連として、str_replaceとpreg_replaceでの置換文字列に特定の文字が含まれるか確認する方法配列を文字列に変換する方法もあわせて読むと、PHPの文字列処理に強くなれます。