PHP
正規表現
初心者

マルチバイト(全角スペース等)対応のtrim処理

More than 1 year has passed since last update.

マルチバイト(全角スペース等)対応のtrim処理

ワリと需要のある処理だと思いますが、改めてググってみるとあまりマネして欲しくないコードが散見されたため、この記事を書いてみました。

  • 検索結果上位のページのコードをコピペで使ってる人
  • 正規表現の \A と \z++\p{C} という書き方を知らない人

などに参考にして頂ければ幸いです。


コード

function mbTrim($pString)
{
    return preg_replace('/\A[\p{C}\p{Z}]++|[\p{C}\p{Z}]++\z/u', '', $pString);
}

解説

要するに、文字列の前後から、空白文字や改行の他 通常は不要と思われる制御文字なんかもまとめて全部削除しちゃえ!という意味になります。

スペース1つとっても、半角・全角以外にも色々とあります(Wikipedia)。それらを1つ1つ調べ上げるのは面倒なので、Unicode 文字プロパティを使って楽をしているという事です。


別のコード

もう少しマイルドに、PHP本来の trim() に全角スペースの処理を加えた程度のもので良いのであれば…

$str = preg_replace('/\A[\x00\s]++|[\x00\s]++\z/u', '', $str);

mb_regex_encoding('UTF-8');
$str = mb_ereg_replace('\A[\x00\s]++|[\x00\s]++\z', '', $str);

…ぐらいで良いと思います。

ただしこの場合、HTMLの   にあたる NO-BREAK SPACE(U+00A0 "\xC2\xA0") は削除されない 点には特に注意してください。


あまりマネしたくないコード

以上となりますが、ググった際に見つけた、あまりマネしたくないコードを解説してみます。

その1

$str = trim(mb_convert_kana($str, 's'));

マネしたくない理由

悪い意味でPHPらしいコードというか…パッと見で「何か気持ち悪い」と感じてしまうのは私だけでしょうか?

$str = '  あ い う え お  ';
$str = trim(mb_convert_kana($str, 's'));

を実行してみると分かると思いますが、このコードでは文字列の途中にある全角スペースまで半角スペースに置換されてしまいます。

手っ取り早い方法ではありますが、このような考え方はバグの原因になりますので、避けた方が良いのではないかと思います。

その2

$str = preg_replace('/^[  ]+/u', '', $str);
$str = preg_replace('/[  ]+$/u', '', $str);

…は流石にアレなので3、選択肢を意味するメタ文字を使って…

$str = preg_replace('/^[  ]+|[  ]+$/u', '', $str);

…と、とりあえず1行にまとめてみます。

マネしたくない理由

PHPマニュアルの trim() を見てみれば分かりますが、trim() ではデフォルトでスペース以外の文字 "\t\n\r\0\x0B" の除去も行っていますが、このコードではそれらが考慮されていません。

また、文字クラス [ ] の中に全角スペースを直接書くというのもあまり感心はしないです。

全角スペース(U+3000 "\xE3\x80\x80")・SPACE(U+0020 "\x20")・NO-BREAK SPACE(U+00A0 "\xC2\xA0") 等の空白文字は、環境によっては見た目の区別がほとんど付かなくなりますので、この手の文字列処理は、16進コード等の別の方法で書く癖を付けておいた方が良いのではないかと思います。



  1. rubyを使ってる人にはお馴染みでしょうが、PHPではまだまだ浸透してないような気がします。 

  2. バックトラックを抑える = パフォーマンスが上がるという事になります。詳細はググってください。 

  3. このように書いてるコードが検索結果上位にたくさん出てくるのは、非常に残念に思います。