PHPで文字列の先頭・末尾の空白を削除する方法|trimと全角スペースの注意

PHPでユーザー入力などを扱うとき、文字列の前後の空白を取り除く処理は頻出します。基本は trim() ですが、日本語の全角スペース( )は trim() では消えないという落とし穴があります。この記事では trim 系の使い方と、全角スペースを安全に取り除く方法までまとめます。

この記事の結論:前後の空白削除は trim()、先頭だけは ltrim()、末尾だけは rtrim()。ただし全角スペースは既定では消えません。全角も消すなら preg_replace('/^[\s ]+|[\s ]+$/u', '', $s) を使います(trim($s, " ") は多バイト文字を壊すので使わない)。
スポンサーリンク

trim・ltrim・rtrimの基本

trim() は前後、ltrim() は先頭(左)、rtrim() は末尾(右)の空白を取り除きます。

trim / ltrim / rtrim
<?php
$s = "   こんにちは   ";

echo "[" . trim($s)  . "]"; // [こんにちは]
echo "[" . ltrim($s) . "]"; // [こんにちは   ]
echo "[" . rtrim($s) . "]"; // [   こんにちは]

これらが既定で取り除くのは、次の文字です。半角スペース・タブ・改行・キャリッジリターン・NUL・垂直タブ" \t\n\r\0\x0B")です。

注意:全角スペースはtrimでは消えない

既定の対象に全角スペース( =U+3000)は含まれません。日本語フォームでは全角スペースが混ざりやすいため、これが落とし穴になります。

全角スペースは残る
<?php
$s = "  あいう  "; // 前後は全角スペース
echo "[" . trim($s) . "]"; // [  あいう  ](変化なし)
trim($s, " ") のように全角を文字マスクに足すのは危険です。trim()バイト単位で処理するため、3バイトの全角スペースを消そうとして隣の多バイト文字を途中から削り、文字化けします(実際に "  あいう  " が壊れた文字列になります)。

全角スペースも安全に取り除くには、preg_replace()/u(UTF-8)修飾子を付けて使います。

OK: preg_replaceで全角スペースも安全に削除
<?php
$s = "  あいう  ";

// 前後の半角・全角スペースや空白をまとめて削除(/u が必須)
$result = preg_replace('/^[\s ]+|[\s ]+$/u', '', $s);
echo "[" . $result . "]"; // [あいう]

特定の文字を取り除く(第2引数)

trim() の第2引数で、取り除く文字を指定できます。ただしこれは「部分文字列」ではなく「文字の集合」である点に注意してください。"XYZ" を指定すると「X・Y・Z のいずれか」を前後から取り除きます(半角ASCII文字なら安全です)。

文字マスクは集合(部分文字列ではない)
<?php
echo trim("XYZこんにちはXYZ", "XYZ"); // こんにちは(X/Y/Z を除去)

// 集合なので、含まれる文字が前後にある限り削られる
echo trim("xxyzABCzyx", "xyz");       // ABC
範囲指定(例: "a..z")も使えます。文字列の置換全般はstr_replaceとpreg_replaceでの文字列置換、パターン確認は文字列内の特定の文字やパターンを確認する方法を参照してください。

文字列中のすべての空白を除去したい場合

trim 系は前後だけです。途中も含めてすべての空白を消すならpreg_replace() を使います(全角対応は /u  を含める)。

すべての空白を除去
<?php
$s = "a b c\td";
echo preg_replace('/[\s ]+/u', '', $s); // abcd

よくある質問(FAQ)

Qtrimで全角スペースが消えないのはなぜですか?
Atrim() の既定の対象に全角スペース(U+3000)が含まれていないためです。全角も消したい場合は preg_replace('/^[\s ]+|[\s ]+$/u', '', $s) を使ってください。
Qtrim($s, “ ”) で全角スペースを消してはダメですか?
Aダメです。trim() はバイト単位で動くため、3バイトの全角スペースを消そうとして隣の日本語文字を壊し、文字化けします。全角を扱うときは必ず /u 付きの preg_replace() を使ってください。
Qtrimの第2引数は部分文字列ですか?
Aいいえ、文字の集合です。trim($s, "XYZ") は「X・Y・Z のいずれか」を前後から取り除きます。「XYZ」という連続文字列を消すわけではありません。
Q先頭だけ・末尾だけ消したいです。
A先頭だけなら ltrim()、末尾だけなら rtrim() を使います。どちらも第2引数で取り除く文字を指定できます。

まとめ

PHPで前後の空白を削除するポイントを整理します。

  • 前後は trim()、先頭は ltrim()、末尾は rtrim()
  • 既定では全角スペースは消えない
  • trim($s, " ") は多バイト文字を壊すので使わない
  • 全角も消すなら preg_replace('/^[\s ]+|[\s ]+$/u', '', $s)
  • 第2引数の文字マスクは部分文字列でなく文字の集合

関連として、str_replaceとpreg_replaceでの置換substrとmb_substrの使い方文字列パターンの確認方法もあわせて読むと、PHPの文字列処理に強くなれます。