[PHP] 複数の区切り文字で文字列を分割

Pocket

文字列を与えるとそれを文に分割してくれる関数が欲しい。PHPにはmb_splitがあるので、たとえば中国語の文字列を文に分割したい場合、以下のようにすればうまくいきそうである。

$target = "5月29日,尼泊尔首都加德满都皇宫博物馆前,庆祝人类登顶珠峰60周年总结表彰颁奖大会隆重举行。登顶珠峰及其各项记录保持者、首次登顶珠峰者的家属等汇聚一堂,享受应有的荣耀。尼泊尔艺术工作者和民间艺人表演了精彩的节目。为期四天的尼泊尔庆祝人类登顶珠峰60周年庆祝活动由此落幕。"
$delimiters = '(。"|。”|?”|!”|。|;|!|?|;|!|?|n)';
$result= mb_split($delimiters, $target);
print_r($result);
Array
(
    [0] => 529日,尼泊尔首都加德满都皇宫博物馆前,庆祝人类登顶珠峰60周年总结表彰颁奖大会隆重举行
    [1] => 登顶珠峰及其各项记录保持者、首次登顶珠峰者的家属等汇聚一堂,享受应有的荣耀
    [2] => 尼泊尔艺术工作者和民间艺人表演了精彩的节目
    [3] => 为期四天的尼泊尔庆祝人类登顶珠峰60周年庆祝活动由此落幕
    [4] => 
)

うまくいってるように見えるが、句点がなくなってしまった。残念だがこれでは不便なので mb_split の代わりになる自前の関数を作ることにする。

function multiple_split($delimiters, $str) {
  $replace = "";
  $bom = html_entity_decode("&#feff", ENT_NOQUOTES, "UTF-8");
  foreach($delimiters as $delm) {
    $replace = $delm . $bom;
    $str = mb_ereg_replace(preg_quote($delm), $replace, $str);
    #preg_quoteをかまさないと正規表現のコンパイルエラーが発生することがある(?など)
  }
  return explode($bom, $str);
}

区切り文字の後ろに適当な文字(ここではUnicodeのBOM)を加え、それを目印にexplodeしている。結果は次の通り。

$delimiters = array('。"', '。”', '?”', '!”', '。', ';', '!', '?', ';' , '!','?', 'n');
$result= multiple_split($delimiters, $target);
print_r($result);
Array
(
    [0] => 529日,尼泊尔首都加德满都皇宫博物馆前,庆祝人类登顶珠峰60周年总结表彰颁奖大会隆重举行。
    [1] => 登顶珠峰及其各项记录保持者、首次登顶珠峰者的家属等汇聚一堂,享受应有的荣耀。
    [2] => 尼泊尔艺术工作者和民间艺人表演了精彩的节目。
    [3] => 为期四天的尼泊尔庆祝人类登顶珠峰60周年庆祝活动由此落幕。
    [4] => 
)

追記:2つめの関数でうまくいったと思っていたが、「。”」などの処理に失敗していたorz 気を取り直してもういっちょ。

function multiple_split($delimiters, $str) {
	$bom = html_entity_decode("&#feff", ENT_NOQUOTES, "UTF-8");
	$str = mb_ereg_replace($delimiters, "\1$bom", $str);
	return explode($bom, $str);
}
$delimiters = '(。"|?"|!"|。”|?”|!”|?”|!”|。|;|!|?|;|!|?|n)';
$result= multiple_split($delimiters, $target);
print_r($result);
Array
(
    [0] => 529日,尼泊尔首都加德满都皇宫博物馆前,庆祝人类登顶珠峰60周年总结表彰颁奖大会隆重举行。
    [1] => 登顶珠峰及其各项记录保持者、首次登顶珠峰者的家属等汇聚一堂,享受应有的荣耀。
    [2] => 尼泊尔艺术工作者和民间艺人表演了精彩的节目。
    [3] => 为期四天的尼泊尔庆祝人类登顶珠峰60周年庆祝活动由此落幕。
    [4] => 
)

コメントする

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください