フォームのバリデーションなどで「文字列が半角だけで構成されているか」をチェックしたい場面はよくあります。基本は正規表現で判定できますが、ここには見落としやすい落とし穴があります。
それは「半角カタカナ(アイウ)も半角」という点です。よく紹介される書き方の多くは半角カナを取りこぼしたり、アクセント文字を誤判定したりします。この記事では、半角の範囲をはっきり決めたうえで正しく判定する方法を解説します。
/^[\x20-\x7E]+$/、半角カナ(アイウ)も半角に含めるなら /^[\x20-\x7E\uFF61-\uFF9F]+$/ を使います。charCodeAt(i) > 0xFF での判定は半角カナやアクセント文字を誤るため使いません。まず「半角」の範囲を決める
「半角」と一口に言っても、対象は1種類ではありません。判定の前に、どこまでを半角とみなすかを決めるのが重要です。
- ASCIIの印字可能文字(U+0020〜U+007E)… 半角の英数字・記号・スペース
- 半角カタカナ・半角記号(U+FF61〜U+FF9F)… アイウ や 。「」 など
とくに見落とされがちなのが半角カナです。アイウ は全角の アイウ とは別物で、れっきとした半角文字です。「半角か」を判定するなら、半角カナを含めるかどうかを最初に決めましょう。
正規表現で判定する(ASCIIの印字可能文字のみ)
半角カナを含めず、半角の英数字・記号・スペースだけを許可する場合は、ASCIIの印字可能範囲 \x20〜\x7E を指定します。
function isHalfWidthAscii(str) {
return /^[\x20-\x7E]+$/.test(str);
}
isHalfWidthAscii("Hello 123!"); // true
isHalfWidthAscii("こんにちは"); // false(全角)
isHalfWidthAscii("アイウ"); // false(半角カナは対象外)
この方式では 半角カナ(アイウ)も false になる点に注意してください。「半角英数字だけ許可したい」用途ならこれで正解です。
半角カナまで含めて判定する
半角カナ(アイウ)も「半角」として許可したい場合は、ASCII範囲に半角カナ・記号の範囲 \uFF61〜\uFF9F を加えます。
function isHalfWidth(str) {
// ASCII印字可能 + 半角カタカナ/記号
return /^[\x20-\x7E\uFF61-\uFF9F]+$/.test(str);
}
isHalfWidth("Hello123"); // true
isHalfWidth("アイウ"); // true ← 半角カナも半角
isHalfWidth("ガギ"); // true ← 濁点付き半角カナもOK
isHalfWidth("こんにちは"); // false(全角)
isHalfWidth("アあ"); // false(全角が混ざる)
住所や氏名の入力で半角カナを許可するフォームなどでは、こちらの範囲指定が適切です。
charCodeAt > 0xFF を使ってはいけない
「文字コードが 0xFF(255)を超えたら全角」という判定をよく見かけますが、これは不正確です。次の2点で誤判定します。
function badCheck(str) {
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 0xFF) return false; // 全角とみなす
}
return true;
}
badCheck("café"); // true ← é(U+00E9)を半角扱い(ASCII正規表現は false で食い違う)
badCheck("ア"); // false ← 半角カナ(U+FF71)を全角扱い(本当は半角なのに)
0xFF を超えるので「全角」と誤判定されます。②アクセント文字や記号(é, ©, ® など U+0080〜00FF)は 0xFF 以下なので「半角」と誤判定されます。さらに charCodeAt はUTF-16単位を返すため、絵文字などのサロゲートペアでも破綻します。判定は正規表現で範囲を明示するのが確実です。空文字をどう扱うか
正規表現の量指定子に注意します。* は0文字以上にマッチするため、空文字 "" も true になります。「1文字以上の入力が半角か」を見たいなら + を使い、空文字を弾きます。
/^[\x20-\x7E]*$/.test(""); // true … 空文字も許可(* は0文字以上)
/^[\x20-\x7E]+$/.test(""); // false … 空文字を弾く(+ は1文字以上)
必須入力のバリデーションでは +、「入力されていれば半角か」を見るなら別途空チェックと組み合わせる、と使い分けます。
用途別の使い分け
「半角かどうか」は目的によって最適な手段が変わります。関連記事も合わせて活用してください。
- 半角の英数字だけに限定したい → 半角英数字かどうかをチェックする方法
- 全角が含まれるかを逆に判定したい → 全角文字をチェックする方法(半角カナの落とし穴も解説)
- 全角を半角に変換してから揃えたい → 全角を半角に変換する方法
よくある質問(FAQ)
/^[\x20-\x7E]+$/.test(str)、半角カナ(アイウ)も含めるなら /^[\x20-\x7E\uFF61-\uFF9F]+$/.test(str) を使います。何を半角とみなすかを先に決めるのがポイントです。/^[\x20-\x7E]+$/ のようなASCIIのみの正規表現では弾かれてしまうため、許可したい場合は \uFF61-\uFF9F を範囲に加えてください。0xFF を超えるため「全角」と誤判定し、アクセント文字(U+0080〜00FF)は 0xFF 以下のため「半角」と誤判定します。さらにサロゲートペアでも破綻します。正規表現で範囲を明示するのが確実です。まとめ
文字列が半角かどうかの判定は、まず「半角」の範囲を決めることから始めます。ASCIIの印字可能文字だけなら /^[\x20-\x7E]+$/、半角カナ(アイウ)も含めるなら /^[\x20-\x7E\uFF61-\uFF9F]+$/ を使い分けます。
charCodeAt(i) > 0xFF での判定は、半角カナを全角扱い・アクセント文字を半角扱いしてしまうため避けましょう。正規表現で範囲を明示するのが、もっとも確実で読みやすい方法です。
