PHP Tips | 文字列処理:基本操作 – 連続スペースを1つにまとめる

PHP PHP
スポンサーリンク

「連続スペースを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. 全角スペースを半角に寄せる
  2. 連続スペースを1つにまとめる
  3. 前後のスペースを削る

という流れを一つの関数にしておくと、「文字列のスペース周りを一気に正規化する」ことができます。


まとめ:今日から使える「連続スペースを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

もし今、あなたのコードの中で「ユーザー入力をそのまま使っているところ」や「検索条件に文字列を使っているところ」があれば、そこにこの正規化処理を一段かませるだけで、かなりトラブルが減ります。

タイトルとURLをコピーしました