フォームの入力チェックなどで、文字列が全角かどうかを判定したい場面はよくあります。ところが「ASCII以外=全角」という素朴な判定は間違いで、半角カタカナまで全角と誤判定してしまいます。正規表現でUnicodeの範囲を指定するのが正しい方法です。
この記事の結論:全角判定は正規表現でUnicodeの範囲を指定します。全部が全角かは
/^[全角の範囲]+$/.test(str)、全角を含むかは /[全角の範囲]/.test(str) です。「ASCII以外=全角」という判定は半角カナを誤判定するので使いません。よくある誤り:「ASCII以外=全角」は間違い
「文字コードが 0x20〜0x7E(ASCII)の範囲外なら全角」という判定を見かけますが、これは誤りです。ASCII以外の文字には半角カタカナ・アクセント付き文字・絵文字なども含まれ、これらは全角ではないからです。
NG: 非ASCIIを全角とみなす判定
function isZenkaku(str) {
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i);
if (code < 0x20 || code > 0x7E) return true; // 非ASCII=全角と誤認
}
return false;
}
console.log(isZenkaku("アイウ")); // true ← 半角カナなのに全角扱い(誤り)
console.log(isZenkaku("café")); // true ← é は全角でない
console.log(isZenkaku("Aあ")); // true ← 全部が全角ではないのに true
半角カタカナ(
アイウ)は「半角」です。文字コード的にはASCII外(U+FF61〜FF9F)ですが、表示幅は半角なので全角に含めてはいけません。この点を取りこぼすと、半角カナ入力が全角チェックをすり抜けてしまいます。全角文字の正しいUnicode範囲
「全角」として扱う主な範囲は次のとおりです。これらをまとめた文字クラスで判定します。
| 種類 | Unicode範囲 | 例 |
|---|---|---|
| 全角スペース・記号・かな・カナ | \u3000-\u30FF |
あ ア ー |
| CJK漢字 | \u3400-\u9FFF |
日 本 語 |
| 全角英数・記号 | \uFF01-\uFF60 |
A 1 ! |
| 全角通貨記号など | \uFFE0-\uFFE6 |
¥ ₩ |
半角カタカナ(
\uFF61-\uFF9F)はあえて含めません。上の範囲に含まれないため、半角カナは「全角ではない」と正しく判定されます。文字列が「すべて全角」かを判定する
先頭から末尾まで全角だけかを調べるには、^...+$(全体一致)の正規表現を使います。
isAllZenkaku:全部が全角か
function isAllZenkaku(str) {
return /^[\u3000-\u30FF\u3400-\u9FFF\uFF01-\uFF60\uFFE0-\uFFE6]+$/.test(str);
}
console.log(isAllZenkaku("あいうえお")); // true
console.log(isAllZenkaku("ABC123")); // true(全角英数)
console.log(isAllZenkaku("日本語")); // true
console.log(isAllZenkaku("アイウ")); // false(半角カナ)
console.log(isAllZenkaku("ABC")); // false(半角英数)
console.log(isAllZenkaku("Aあ")); // false(半角が混在)
全角文字を「含む」かを判定する
1文字でも全角が含まれるかを調べるなら、^ と $ を外して部分一致にします。
hasZenkaku:全角を含むか
function hasZenkaku(str) {
return /[\u3000-\u30FF\u3400-\u9FFF\uFF01-\uFF60\uFFE0-\uFFE6]/.test(str);
}
console.log(hasZenkaku("Aあ")); // true(あ が全角)
console.log(hasZenkaku("ABC")); // false
console.log(hasZenkaku("アイウ")); // false(半角カナのみ)
「すべて全角か」と「全角を含むか」は別物です。入力欄を「全角のみ許可」したいなら
isAllZenkaku、「全角が紛れていないか」を検知したいなら hasZenkaku を使い分けます。ひらがな・カタカナ・漢字を個別に判定する
「ひらがなのみ」「カタカナのみ」など、より細かく判定したいときは範囲を絞ります。
種類別の判定
// ひらがなのみ(長音符 ー も許可)
const isHiragana = (s) => /^[\u3041-\u3096\u30FC]+$/.test(s);
// 全角カタカナのみ(長音符 ー も許可)
const isKatakana = (s) => /^[\u30A1-\u30F6\u30FC]+$/.test(s);
// 漢字を含む
const hasKanji = (s) => /[\u3400-\u9FFF]/.test(s);
// 全角英数のみ
const isZenkakuAlnum = (s) => /^[\uFF01-\uFF5E]+$/.test(s);
console.log(isHiragana("あいう")); // true
console.log(isKatakana("アイウ")); // true
console.log(hasKanji("日本語")); // true
console.log(isZenkakuAlnum("ABC1")); // true
実用例:フォームの全角バリデーション
全角のみ許可する入力チェック
const input = document.getElementById("kana");
input.addEventListener("input", () => {
const value = input.value;
const ok = value === "" || /^[\u3000-\u30FF\u3400-\u9FFF\uFF01-\uFF60]+$/.test(value);
input.setCustomValidity(ok ? "" : "全角で入力してください");
});
逆に「半角で入力させたい」場合は文字列が半角かどうかをチェックする方法、入力後に変換したい場合は全角を半角に変換する方法も参考になります。
よくある質問(FAQ)
Q文字列が全角かどうかを判定するには?
A正規表現でUnicodeの範囲を指定します。すべて全角かは
/^[\u3000-\u30FF\u3400-\u9FFF\uFF01-\uFF60]+$/.test(str)、全角を含むかは ^ と $ を外して判定します。「ASCII以外=全角」は半角カナを誤判定するので使いません。Q半角カタカナはなぜ全角に含めないのですか?
A半角カタカナ(
アイウ、U+FF61〜FF9F)は表示幅が半角だからです。文字コード上はASCII外ですが全角ではないため、全角チェックの範囲(\u3000〜など)には含めません。Qひらがなのみ・カタカナのみを判定するには?
Aひらがなは
/^[\u3041-\u3096\u30FC]+$/、カタカナは /^[\u30A1-\u30F6\u30FC]+$/ で判定できます。長音符「ー」(\u30FC)を許可するかは用途に合わせて調整してください。Qフォームの全角チェックはどこで行うべきですか?
AUXのため
input イベントでリアルタイムに確認し、送信前にも submit で最終確認します。サーバー側でも同じチェックを行うと、より安全なバリデーションになります。まとめ
JavaScriptで全角文字を正しく判定するポイントを整理します。
- 「ASCII以外=全角」は誤り(半角カナを誤判定する)
- 全角は正規表現でUnicode範囲を指定(
\u3000-\u30FFほか) - すべて全角かは
/^[...]+$/、含むかは/[...]/ - 半角カタカナ(
\uFF61-\uFF9F)は全角に含めない - ひらがな・カタカナ・漢字・全角英数は範囲を絞って個別判定できる
関連として、文字列が半角かどうかをチェックする方法・半角英数字かどうかをチェックする方法・全角を半角に変換する方法もあわせて読むと、文字種の判定・変換に強くなれます。
