【JavaScript】全角を半角に変換する方法|英字・数字・記号・スペース・カタカナを正規化する

フォーム入力やCSVなどのテキスト処理では、「ABC123」のような全角文字を半角に正規化したい場面がよくあります。全角と半角が混在するとデータの突合や検索がうまくいかないためです。

ポイントは、全角の英数記号は文字コードが半角のちょうど 0xFEE0(10進で65248)大きいという規則です。これを使えば英字・数字・記号をまとめて変換できます。ただしカタカナだけはこの規則が使えず、対応表が必要です。順に見ていきましょう。

この記事の結論:全角の英数記号は str.replace(/[!-~]/g, c => String.fromCharCode(c.charCodeAt(0) - 0xFEE0)) で一括変換できます。全角スペースは別途   → 半角スペースに置換、カタカナは対応表で変換します。
スポンサーリンク

全角の英数記号を半角に変換する(推奨)

全角の記号〜英数字は U+FF01〜U+FF5E)に並んでおり、半角の U+0021〜U+007E!~)とちょうど 0xFEE0 ずれているだけです。これを引けば一括変換できます。全角スペース(U+3000)だけは別に置換します。

全角英数記号+スペースを半角に
function toHalfWidth(str) {
  return str
    .replace(/[!-~]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xFEE0))
    .replace(/ /g, " "); // 全角スペース(U+3000) → 半角スペース
}

console.log(toHalfWidth("Ab123!? z")); // "Ab123!? z"
console.log(toHalfWidth("TEL:03-1234")); // "TEL:03-1234"
0xFEE065248 と同じ値です。全角の「A」(U+FF21) から 0xFEE0 を引くと半角「A」(U+0041) になります。

アルファベット・数字だけを変換する

記号は変換せず、英字だけ・数字だけを変換したい場合は対象範囲を絞ります。

英字だけ / 数字だけ変換
// 全角アルファベットだけ(大文字・小文字は保持される)
function alphaToHalf(str) {
  return str.replace(/[A-Za-z]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xFEE0));
}
console.log(alphaToHalf("ABCdef")); // "ABCdef"(小文字はそのまま小文字)

// 全角数字だけ
function digitToHalf(str) {
  return str.replace(/[0-9]/g, (c) => String.fromCharCode(c.charCodeAt(0) - 0xFEE0));
}
console.log(digitToHalf("0123")); // "0123"
大文字・小文字は変わりません。ABCABCdefdef のように、全角→半角の変換は大小をそのまま保持します(大文字化したい場合は別途 toUpperCase() が必要)。

全角カタカナを半角カナに変換する

カタカナは英数記号のような一定のオフセットでは変換できません。さらに濁音・半濁音は半角だと2文字になるガ)ため、対応表(マッピング)で変換します。

カタカナの全角→半角(対応表)
// ※主要なものを抜粋。実務で全カナを正確に変換するなら完全な対応表かライブラリを使う
const KANA_MAP = {
  "ガ":"ガ","ギ":"ギ","グ":"グ","ゲ":"ゲ","ゴ":"ゴ", // 濁音は1→2文字
  "パ":"パ","ピ":"ピ","プ":"プ","ペ":"ペ","ポ":"ポ", // 半濁音も1→2文字
  "ア":"ア","イ":"イ","ウ":"ウ","エ":"エ","オ":"オ",
  "カ":"カ","キ":"キ","ク":"ク","ケ":"ケ","コ":"コ",
  "ー":"ー","、":"、","。":"。","「":"「","」":"」","・":"・",
};

function kanaToHalf(str) {
  const re = new RegExp("(" + Object.keys(KANA_MAP).join("|") + ")", "g");
  return str.replace(re, (m) => KANA_MAP[m]);
}

console.log(kanaToHalf("ガパアカ。")); // "ガパアカ。"
濁点()・半濁点()の関係で文字数が増減するため、全カナを正確に扱うなら完全な対応表を用意するか、正規化ライブラリ(例: encoding.js など)を使うのが確実です。

逆:半角を全角に変換する

逆方向は 0xFEE0 を足します(英数記号)。全角スペースも同様に戻します。

半角→全角(英数記号)
function toFullWidth(str) {
  return str
    .replace(/[!-~]/g, (c) => String.fromCharCode(c.charCodeAt(0) + 0xFEE0))
    .replace(/ /g, " "); // 半角スペース → 全角スペース
}

console.log(toFullWidth("Ab1!")); // "Ab1!"

実用例:フォーム入力の正規化

入力された全角の英数記号を半角に揃えてから保存・検索すると、表記ゆれを防げます。

入力値の正規化
const input = document.getElementById("tel");

input.addEventListener("blur", () => {
  // 全角英数記号→半角 + 前後の空白除去
  input.value = toHalfWidth(input.value).trim();
});

// "03-1234-5678" → "03-1234-5678"
関連として、文字幅の数え方は全角を2・半角を1としてカウントする方法、半角英数かどうかの判定は半角英数かどうかをチェックする方法、全角スペースの扱いは全角スペースを半角スペースに変換する方法も参考になります。

変換対象ごとの方法

変換対象 方法
英数記号まとめて /[!-~]/g-0xFEE0
アルファベットだけ /[A-Za-z]/g-0xFEE0
数字だけ /[0-9]/g-0xFEE0
全角スペース / /g → 半角スペース
カタカナ 対応表(オフセット不可・濁点で1→2文字)

よくある質問(FAQ)

Q全角の英数字をまとめて半角にするには?
Astr.replace(/[!-~]/g, c => String.fromCharCode(c.charCodeAt(0) - 0xFEE0)) で全角の記号〜英数字(U+FF01〜U+FF5E)を一括変換できます。全角スペース(U+3000)だけは範囲外なので、別途半角スペースに置換します。
Q0xFEE0(65248)とは何ですか?
A全角の英数記号(U+FF01〜U+FF5E)と、対応する半角(U+0021〜U+007E)のコードポイントの差です。全角から 0xFEE0 を引けば半角に、半角に足せば全角になります。
Q全角カタカナを半角にオフセットで変換できますか?
Aできません。カタカナは英数記号のような一定の差になっておらず、さらに濁音・半濁音は半角だと ガ のように2文字になるため、対応表(マッピング)で変換する必要があります。完全対応はライブラリの利用が確実です。
Q変換しても大文字・小文字はそのままですか?
Aはい。全角→半角は文字コードをずらすだけなので、ABCABCdefdef大小は保持されます。大文字に揃えたい場合は変換後に toUpperCase() を使います。

まとめ

JavaScriptで全角を半角に変換する方法のポイントを整理します。

  • 英数記号は /[!-~]/g で検出し 0xFEE0 を引くだけで一括変換
  • 全角スペース(U+3000)は範囲外なので別途半角スペースに置換
  • 英字だけ・数字だけは対象範囲(A-Z / 0-9)を絞る
  • 大文字・小文字は保持される(大文字化は別途 toUpperCase()
  • カタカナはオフセット不可。対応表で変換(濁点で1→2文字)

関連として、全角2・半角1での文字数カウント半角英数かどうかの判定もあわせて確認すると、全角・半角まわりの処理に強くなれます。