「連続スペースを1つにまとめる」とは何か
PHP で文字列を扱っていると、ユーザー入力や外部データの中に「スペースが連続している」状態がよく紛れ込みます。
例えば、次のような文字列です。
$text = "山田 太郎 さん";
PHP見た目では「ちょっとスペース多いな」くらいですが、実際には
- 「山田」と「太郎」の間に半角スペース3個
- 「太郎」と「さん」の間に半角スペース4個
が入っています。
これをそのまま検索や表示に使うと、
- 見た目が不格好になる
- 「同じはずの文字列」と一致しなくなる
といった問題が起きます。
そこでやりたいのが、
「連続しているスペースを、1つのスペースにまとめる」
という処理です。
なぜ連続スペースを1つにまとめたいのか
「同じ意味なのに違う文字列」問題を防ぐ
例えば、ユーザーが「山田 太郎」と入力したつもりでも、実際にはこうなっていることがあります。
$input1 = "山田 太郎";
$input2 = "山田 太郎";
var_dump($input1 === $input2); // bool(false)
PHP見た目の意味は同じでも、プログラム的には「別の文字列」です。
これが検索条件や重複チェックに絡むと、かなり厄介です。
連続スペースを1つにまとめておけば、どちらも同じ形にそろえられます。
// どちらも「山田 太郎」に正規化できる、というイメージ
表示をきれいに整えたいとき
業務システムの画面や帳票で、スペースがガタガタだと見た目の印象が悪くなります。
特に、ユーザーが自由入力できる「備考」「コメント」欄などでは、スペースが連続しがちです。
連続スペースを1つにまとめることで、
- レイアウトが安定する
- 文字の並びが読みやすくなる
といったメリットがあります。
PHP で連続スペースを1つにまとめる基本パターン
一番シンプルな方法:preg_replace で「2つ以上のスペース」を1つに
PHP で「連続した文字」をまとめて扱いたいときの定番が、正規表現を使う preg_replace です。
まずは半角スペースだけを対象にした、シンプルな例から見てみましょう。
$text = "山田 太郎 さん";
// 半角スペースが2つ以上続いているところを、半角スペース1つに置き換える
$result = preg_replace('/ {2,}/', ' ', $text);
var_dump($result); // string(24) "山田 太郎 さん"
PHPここでのポイントをかみ砕いて説明します。
/ {2,}/ という正規表現は、
" "(半角スペース)が{2,}「2個以上連続しているところ」
を意味します。
つまり、
「半角スペースが2個以上続いている場所を見つけて、そこを半角スペース1個に置き換える」
という処理になります。
タブや改行もまとめて扱いたい場合
「スペースだけでなく、タブや改行も含めて『空白が連続しているところ』を1つにしたい」という場合は、\s を使います。
$text = "山田\t\t太郎 さん\n\nよろしくお願いします。";
// 空白文字(スペース、タブ、改行など)が2つ以上続くところを、半角スペース1つに
$result = preg_replace('/\s{2,}/', ' ', $text);
var_dump($result);
PHP\s は「空白文字全般(スペース、タブ、改行など)」を表します。
この書き方だと、「空白が連続しているところは全部まとめて1つの半角スペースにする」という動きになります。
全角スペースも考慮したい場合
日本語環境の落とし穴:全角スペースは \s に含まれない
日本語入力では、全角スペース(" ")が混ざることがよくあります。
しかし、\s は「半角の空白文字」だけを対象にするため、全角スペースは含まれません。
例えば、次のような文字列を考えます。
$text = "山田 太郎 さん"; // 「山田」と「太郎」の間は全角スペース2つ
このとき、\s{2,} では「全角スペース2つ」は対象になりません。
日本語環境で本気で「連続スペースを1つにまとめる」ことを考えるなら、全角スペースも自分で扱う必要があります。
半角・全角スペースを両方まとめて1つにする例
全角スペースも含めて「連続するスペースを1つにしたい」場合、次のように書けます。
$text = "山田 太郎 さん です";
// 半角スペースまたは全角スペースが2つ以上続くところを、半角スペース1つに
$result = preg_replace('/[ ]{2,}/u', ' ', $text);
var_dump($result); // string(39) "山田 太郎 さん です"
PHPここでのポイントは、
[ ]という文字クラスで「半角スペース」と「全角スペース」の両方を指定している{2,}で「2個以上連続しているところ」を対象にしている/uで「UTF-8 として扱う」ことを指定している
という3点です。
この書き方なら、
- 半角スペースが連続していても
- 全角スペースが連続していても
- 半角と全角が混ざって連続していても
すべて「半角スペース1つ」にまとめることができます。
実務での具体的なシチュエーション例
例題1:氏名のスペースを整える
ユーザーが「姓」と「名」を1つの入力欄に入れるケースを考えます。
$name = "山田 太郎"; // 半角スペース3つ
$name2 = "山田 太郎"; // 全角スペース2つ
PHPこれらを、アプリ内部では「姓と名の間は半角スペース1つ」にそろえたいとします。
function normalizeSpaces(string $text): string
{
// 半角・全角スペースが2つ以上続くところを半角スペース1つに
return preg_replace('/[ ]{2,}/u', ' ', $text);
}
var_dump(normalizeSpaces($name)); // "山田 太郎"
var_dump(normalizeSpaces($name2)); // "山田 太郎"
PHPこうしておけば、
- 表示もきれい
- 検索や比較も安定
という状態にできます。
例題2:自由入力の「備考」欄を整形する
業務システムの「備考」「コメント」欄では、ユーザーがスペースを連打してしまうことがあります。
$comment = "納品は 午前中 希望です。 できれば 早めに。";
PHPこのままだと、画面や帳票で見たときに読みにくくなります。
そこで、連続スペースを1つにまとめます。
function normalizeSpaces(string $text): string
{
return preg_replace('/[ ]{2,}/u', ' ', $text);
}
$comment = normalizeSpaces($comment);
var_dump($comment);
// "納品は 午前中 希望です。 できれば 早めに。"
PHP「意味を変えずに、読みやすさだけ整える」というイメージです。
例題3:CSV や外部データの項目を正規化する
外部システムから受け取ったデータや、CSV インポートしたデータには、スペースがバラバラに入っていることがあります。
$row = [
'code' => "A 001",
'name' => "山田 太郎",
];
PHPこれをアプリ内部で扱いやすい形にそろえるために、連続スペースを1つにまとめます。
function normalizeSpaces(string $text): string
{
return preg_replace('/[ ]{2,}/u', ' ', $text);
}
$row['code'] = normalizeSpaces($row['code']);
$row['name'] = normalizeSpaces($row['name']);
var_dump($row);
PHP結果はこうなります。
array(2) {
["code"]=>
string(5) "A 001"
["name"]=>
string(16) "山田 太郎"
}
このように、「スペースの入り方がバラバラなデータ」を「一定のルールにそろえたデータ」に変換できます。
重要ポイントの深掘り
「何をスペースとして扱うか」を自分で決める
連続スペースを1つにまとめるときに大事なのは、
「自分のシステムでは、何を『スペース』として扱うのか」
をはっきり決めることです。
例えば、次のような選択肢があります。
- 半角スペースだけを対象にする
- 半角スペースとタブ、改行もまとめて扱う
- 半角スペースと全角スペースを対象にする
- 半角・全角・タブ・改行など、全部まとめて1つの半角スペースにする
日本語の業務システムでは、
「半角スペースと全角スペースを対象にする」
という方針を取ることが多いです。
その場合、先ほどのような
preg_replace('/[ ]{2,}/u', ' ', $text);
PHPという書き方が、実務でかなり使える「定番パターン」になります。
「前後のスペース除去」と組み合わせるとさらに安定する
連続スペースを1つにまとめる処理は、「前後のスペースを削る処理」とセットで使うと、よりきれいに整います。
例えば、次のような関数を用意できます。
function normalizeSpacesFull(string $text): string
{
// 1. 全角スペースを半角スペースに
$text = str_replace(" ", " ", $text);
// 2. 連続する半角スペースを1つに
$text = preg_replace('/ {2,}/', ' ', $text);
// 3. 前後のスペースを削る
$text = trim($text);
return $text;
}
$text = " 山田 太郎 ";
var_dump(normalizeSpacesFull($text)); // "山田 太郎"
PHPこのように、
- 全角スペースを半角に寄せる
- 連続スペースを1つにまとめる
- 前後のスペースを削る
という流れを一つの関数にしておくと、「文字列のスペース周りを一気に正規化する」ことができます。
まとめ:今日から使える「連続スペースを1つにまとめる」テンプレ
連続スペースを1つにまとめる処理は、実務で本当によく使う「地味だけど効く」ユーティリティです。
シンプルに半角スペースだけを対象にするなら、次のように書けます。
function collapseSpaces(string $text): string
{
return preg_replace('/ {2,}/', ' ', $text);
}
PHP日本語環境で、半角・全角スペースを両方まとめて扱いたいなら、こちらが実用的です。
function collapseSpacesJa(string $text): string
{
return preg_replace('/[ ]{2,}/u', ' ', $text);
}
PHPさらに、前後のスペース除去まで含めて「スペース周りを全部整える」なら、こういう形もよく使います。
function normalizeSpaces(string $text): string
{
// 全角スペースを半角に
$text = str_replace(" ", " ", $text);
// 連続スペースを1つに
$text = preg_replace('/ {2,}/', ' ', $text);
// 前後のスペースを削除
return trim($text);
}
PHPもし今、あなたのコードの中で「ユーザー入力をそのまま使っているところ」や「検索条件に文字列を使っているところ」があれば、そこにこの正規化処理を一段かませるだけで、かなりトラブルが減ります。
