「連続空白圧縮」とは何をするユーティリティか
まずイメージからいきましょう。
ユーザー入力や外部データには、よくこんな文字列が紛れ込みます。
"山田 太郎"
" 東京都 中央区 "
"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やっていることを噛み砕きます。
value が null / 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"
JavaScriptCSV 出力、ログ出力、検索条件など、
「1行で扱いたいけれど、元の区切り感は残したい」場面でとても役立ちます。
業務での具体的な使いどころ
名前・住所などの入力値の整形
ユーザーがフォームに入力するとき、スペースの入れ方はバラバラです。
"山田 太郎"
" 山田 太郎"
"山田太郎"
検索や表示を安定させるために、
保存前や検索前に一度 normalizeSpaces を通しておくと、
「スペースの入れ方の違い」に振り回されにくくなります。
検索条件の正規化
検索ボックスに複数キーワードを入れるような UI では、
ユーザーがスペースを何個入れても、同じように扱いたいです。
const raw = " 東京 中央区 物件 ";
const normalized = normalizeSpaces(raw); // "東京 中央区 物件"
const keywords = normalized.split(" "); // ["東京", "中央区", "物件"]
JavaScriptこうしておくと、
「東京 中央区」
「東京 中央区」
「 東京 中央区 」
どれで検索しても、同じキーワード配列になります。
ログや CSV の見やすさ向上
ログや CSV に出す文字列に、
タブや連続スペースが混ざっていると、
ツールによっては見づらくなったり、意図しない列ズレを起こしたりします。
出力前に collapseSpaces や toOneLine を通しておくと、
「人間が読む」「ツールで扱う」両方の観点で安定します。
設計として意識してほしいこと
「どこまでやるか」をユーティリティごとに分ける
連続空白圧縮には、実は段階があります。
連続空白だけを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) と書いている状態」から
「意図を持って設計された空白整形ユーティリティ」を持つ状態に、一段レベルアップします。
