JavaScript Tips | 文字列ユーティリティ:整形 - 全角→半角

JavaScript JavaScript
スポンサーリンク

「全角→半角」ユーティリティは何を解決してくれるのか

まず、よくある業務の“あるある”からいきます。
ユーザーが「1234」と全角数字で入力してくる。
「@」や「-」が全角のせいでメールアドレス判定に落ちる。
検索キーワードが「ABC」と全角のせいでヒットしない。

見た目は「1234」「ABC」と同じでも、コンピュータ的には別の文字です。
この「見た目は同じだけど別物」というギャップを埋めるのが、
全角→半角ユーティリティの役割です。


まずは対象を決める:何を半角にするのか

全角→半角と一口に言っても、対象はいろいろあります。
全角数字(0〜9)
全角英字(A〜Z、a〜z)
全角記号(@、-、()など)
全角スペース

業務で一番よく使うのは「数字」「英字」「記号」「スペース」です。
まずは「数字と英字とスペースだけ」から始めて、
必要に応じて記号を足していく、という設計が扱いやすいです。


基本形:全角数字・英字・スペースを半角にする

文字コードの差を利用したシンプル実装

全角の英数字は、半角と「一定の差」を持ったコードになっています。
これを利用すると、比較的シンプルに変換できます。

function toHalfWidthBasic(str) {
  if (str == null) return "";

  return String(str).replace(/[!-~]/g, (ch) => {
    const code = ch.charCodeAt(0);
    return String.fromCharCode(code - 0xFEE0);
  }).replace(/ /g, " ");
}
JavaScript

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

正規表現 [!-~] は、「全角の ! から全角の ~ まで」の範囲を表す。
その範囲の文字は、半角版とコードポイントの差が 0xFEE0 だけ離れている。
code - 0xFEE0 で半角側の文字に変換できる。
全角スペース()は、別途 " " に置き換える。

使い方はこうです。

toHalfWidthBasic("123ABC abc テスト");
// "123ABC abc テスト"
JavaScript

日本語(ひらがな・カタカナ・漢字)はそのまま残り、
英数字と記号とスペースだけが半角になります。


もう少し実務寄りにする:null や undefined への対応

フォームや API から来る値は、必ずしも「きれいな文字列」とは限りません。
null や undefined が紛れ込むこともあります。
それでエラーになるのは避けたいので、ユーティリティ側で吸収しておきます。

function toHalfWidth(str) {
  if (str == null) return "";

  const s = String(str);

  return s.replace(/[!-~]/g, (ch) => {
    const code = ch.charCodeAt(0);
    return String.fromCharCode(code - 0xFEE0);
  }).replace(/ /g, " ");
}
JavaScript

これで、次のような入力にも安全に対応できます。

toHalfWidth(null);          // ""
toHalfWidth(undefined);     // ""
toHalfWidth(123);        // "123"(数値は一度文字列化される)
toHalfWidth(" ABC ");  // " ABC "
JavaScript

「とりあえず文字列として扱いたい」という場面では、
このくらい防御的にしておくと安心です。


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

入力値の正規化(バリデーション前の前処理)

例えば、郵便番号や電話番号の入力欄を考えます。
ユーザーが「123-4567」と全角で入れても、
システム側では「123-4567」として扱いたいはずです。

function normalizePostalCode(input) {
  const half = toHalfWidth(input);
  return half.replace(/[^0-9]/g, ""); // 数字以外を削除
}

normalizePostalCode("123ー4567"); // "1234567"
JavaScript

ここでの重要ポイントは、

全角→半角で「文字の種類」を揃える
そのうえで「数字だけにする」「記号を消す」などの処理をする

という二段構えにしていることです。
これをやっておくと、バリデーションや比較が格段に楽になります。

検索キーワードの正規化

検索機能でも、全角・半角の違いでヒットしない問題がよく起きます。
「ABC」と「ABC」を同じものとして扱いたい場合、
検索前に全角→半角をかけておくのが定番です。

function normalizeKeyword(input) {
  const half = toHalfWidth(input);
  return half.trim().toLowerCase();
}

normalizeKeyword(" ABC "); // "abc"
JavaScript

これで、「全角か半角か」「大文字か小文字か」「前後に空白があるか」といった差を吸収できます。


どこまで変換するかを決めるのが「設計」

全角→半角は便利ですが、「何でもかんでも全部変換すればいい」というものでもありません。
例えば、次のようなケースでは注意が必要です。

ユーザーが意図的に全角記号を使っている(見た目のレイアウトなど)
パスワードやシークレットキーなど、「文字一つ違えば別物」な値

こういったものに勝手に全角→半角をかけると、
ユーザーの意図を壊してしまう可能性があります。

なので、設計としてはこう決めておくと良いです。

ユーザー入力で「英数字・記号の全角は意味がない」項目(ID、メール、検索、コードなど)には積極的に使う。
意味が変わる可能性がある項目(パスワード、自由テキストなど)には安易に使わない。

「どの項目に全角→半角をかけるか」を仕様として明文化しておくと、
チーム開発でもブレにくくなります。


小さな練習で感覚をつかむ

コンソールでいくつか試してみてください。

toHalfWidth("0123456789");
toHalfWidth("ABCabc");
toHalfWidth("!@#$% &");
toHalfWidth("テスト123ABC");
JavaScript

どの文字がどう変わるかを目で見て確認すると、
「全角→半角の変換範囲」と「日本語はそのまま残る」感覚がつかめます。

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

export function toHalfWidth(str) { ... }
JavaScript

を一つ置いて、
「英数字を扱う前に必ずここを通す」
というルールにしてみてください。

それができた瞬間、あなたの文字列処理は
「ユーザー入力に振り回される側」から
「入力をこちらの都合に正規化してから扱う側」に変わります。

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