JavaScript Tips | 文字列ユーティリティ:検索・置換 - 連続空白圧縮

JavaScript JavaScript
スポンサーリンク

「連続空白圧縮」とは何をするユーティリティか

まずイメージからいきましょう。
ユーザー入力や外部データには、よくこんな文字列が紛れ込みます。

"山田   太郎"
"  東京都   中央区   "
"a    b        c"

人間からすると「スペース多いな」くらいですが、
プログラム的には「どこまでが名前で、どこからが苗字か」「検索でヒットしない」など、地味に効いてきます。

連続空白圧縮は、
「連続している空白(スペースやタブなど)を、1個だけにまとめる」処理です。

"山田   太郎" → "山田 太郎"
"  東京都   中央区   " → " 東京都 中央区 "
"a    b        c" → "a b c"

見た目も整うし、検索や比較も安定する——そんな小さいけれど効き目の大きいユーティリティです。


まずは「空白とは何か」をざっくり押さえる

空白はスペースだけじゃない

JavaScript で「空白」と言うとき、だいたい次のようなものを含みます。

半角スペース " "
タブ \t
改行 \n
復帰 \r
その他の空白文字

正規表現では、これらをまとめて \s で表現できます。
つまり、\s+ は「空白文字が1文字以上連続しているところ」という意味になります。


連続空白圧縮の基本実装

一番よく使うパターン

「空白が連続していたら、1個の半角スペースにまとめる」ユーティリティは、こう書けます。

function collapseSpaces(value) {
  if (value == null) return "";

  return String(value).replace(/\s+/g, " ");
}
JavaScript

やっていることを噛み砕きます。

valuenull / undefined でも落ちないようにしている。
String(value) で文字列に変換してから処理している。
/\s+/g で「空白文字が1文字以上続くところ」を全部探している。
それを " "(半角スペース1個)に置き換えている。

これだけで、「連続空白圧縮」の基本は完成です。

動きの確認

collapseSpaces("山田   太郎");        // "山田 太郎"
collapseSpaces("  東京都   中央区   "); // " 東京都 中央区 "
collapseSpaces("a\t\tb   c");        // "a b c"(タブもまとめてスペースに)
JavaScript

「空白がどれだけ連続していても、結果はスペース1個」にそろえられているのが分かると思います。


もう一歩丁寧に:前後の空白も整える

「中の空白は1個」「前後は削る」というよくある要件

実務では、

単語と単語の間はスペース1個にしたい。
文字列の先頭と末尾の空白は要らない。

という要件がセットで出てくることが多いです。

その場合は、こういうユーティリティにします。

function normalizeSpaces(value) {
  if (value == null) return "";

  return String(value)
    .replace(/\s+/g, " ") // 連続空白を1個に
    .trim();              // 前後の空白を削除
}
JavaScript

動きの確認

normalizeSpaces("  山田   太郎  "); // "山田 太郎"
normalizeSpaces(" a\t\tb   c ");    // "a b c"
JavaScript

これで、「中はきれいに1個」「前後はスッキリ」という、
人間にとって自然な形に整えられます。


改行と組み合わせた「1行化+連続空白圧縮」

改行も含めて「1行のテキスト」にしたいとき

テキストエリアの入力や外部データには、改行も混ざります。
「改行をスペースに変えて、さらに連続空白もまとめて、1行にしたい」というのはよくあるパターンです。

function toOneLine(value) {
  if (value == null) return "";

  return String(value)
    .replace(/\r?\n/g, " ") // 改行をスペースに
    .replace(/\s+/g, " ")   // 連続空白を1個に
    .trim();                // 前後の空白を削除
}
JavaScript

動きの確認

toOneLine("山田太郎\n東京都   中央区");
// "山田太郎 東京都 中央区"

toOneLine("行1\r\n  行2\r\n\r\n行3");
// "行1 行2 行3"
JavaScript

CSV 出力、ログ出力、検索条件など、
「1行で扱いたいけれど、元の区切り感は残したい」場面でとても役立ちます。


業務での具体的な使いどころ

名前・住所などの入力値の整形

ユーザーがフォームに入力するとき、スペースの入れ方はバラバラです。

"山田   太郎"
"  山田 太郎"
"山田太郎"

検索や表示を安定させるために、
保存前や検索前に一度 normalizeSpaces を通しておくと、
「スペースの入れ方の違い」に振り回されにくくなります。

検索条件の正規化

検索ボックスに複数キーワードを入れるような UI では、
ユーザーがスペースを何個入れても、同じように扱いたいです。

const raw = "  東京   中央区  物件 ";
const normalized = normalizeSpaces(raw); // "東京 中央区 物件"
const keywords = normalized.split(" ");  // ["東京", "中央区", "物件"]
JavaScript

こうしておくと、

「東京 中央区」
「東京 中央区」
「 東京 中央区 」

どれで検索しても、同じキーワード配列になります。

ログや CSV の見やすさ向上

ログや CSV に出す文字列に、
タブや連続スペースが混ざっていると、
ツールによっては見づらくなったり、意図しない列ズレを起こしたりします。

出力前に collapseSpacestoOneLine を通しておくと、
「人間が読む」「ツールで扱う」両方の観点で安定します。


設計として意識してほしいこと

「どこまでやるか」をユーティリティごとに分ける

連続空白圧縮には、実は段階があります。

連続空白だけを1個にする(前後はそのまま)。
連続空白を1個にして、前後も削る。
改行も含めて1行にして、連続空白を1個にして、前後も削る。

これを全部一つの関数に詰め込むと、
「この関数、何をどこまでやるんだっけ?」と分かりにくくなります。

なので、例えばこう分けるのがおすすめです。

export function collapseSpaces(value) { ... }        // 連続空白 → 1個
export function normalizeSpaces(value) { ... }       // 連続空白 → 1個 + 前後 trim
export function toOneLine(value) { ... }             // 改行→スペース + 連続空白 → 1個 + 前後 trim
JavaScript

関数名を見ただけで「意図」が分かるようにしておくと、
後から読む人にも優しいコードになります。

「どのタイミングで正規化するか」を決める

入力直後に正規化するのか。
保存前に正規化するのか。
検索前や出力前だけ正規化するのか。

これはシステム設計の話ですが、
大事なのは「ブレさせない」ことです。

個人的には、

保存するデータはなるべく元の入力を持つ。
検索や出力など「扱いやすさが重要な場面」で正規化する。

という方針が、トラブルが少なくて好きです。


ちょっとだけ手を動かしてみる

コンソールで、次のあたりを試してみてください。

collapseSpaces("山田   太郎");
normalizeSpaces("  山田   太郎  ");
toOneLine("山田太郎\n東京都   中央区");
JavaScript

「どこまでがそのままで、どこからが整えられるか」を目で確認すると、
連続空白圧縮のイメージがかなりクリアになります。

そのうえで、自分のプロジェクトに

export function collapseSpaces(value) { ... }
export function normalizeSpaces(value) { ... }
export function toOneLine(value) { ... }
JavaScript

のようなユーティリティを一つ置いて、
「空白を整えたいときは必ずここを通す」
というルールにしてみてください。

それができた瞬間、あなたの文字列処理は
「その場しのぎで replace(/\s+/g) と書いている状態」から
「意図を持って設計された空白整形ユーティリティ」を持つ状態に、一段レベルアップします。

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