JavaScript Tips | 文字列ユーティリティ:検証 - 日本語判定

JavaScript JavaScript
スポンサーリンク

「日本語判定」で本当に知りたいことは何か

まずゴールをはっきりさせましょう。
ここでやりたいのは、「この文字列は“日本語を含んでいるか?”を判定するユーティリティを作ること」です。

もう少し分解すると、よくある要件はこんな感じです。

ユーザー名は「日本語を含んでもよい」かどうかをチェックしたい。
商品コードは「日本語を含んではいけない」ので、日本語が混ざっていたら弾きたい。
「説明文は日本語で書いてほしい」ので、日本語が1文字もない場合は警告したい。

つまり、「日本語だけか?」よりも、
「日本語が含まれているか/含まれていないか」を知りたい場面が多いです。

ここをゴールにして話を進めます。


まず「日本語とは何か」をざっくり押さえる

日本語を構成する文字たち

ざっくり言うと、日本語の文字はこんなグループに分けられます。

ひらがな
カタカナ
漢字

これに加えて、「全角の記号」「全角英数字」なども日本語テキストに混ざりがちですが、
まずは 「ひらがな・カタカナ・漢字が1文字でもあれば“日本語を含む”とみなす」 くらいから始めるのが現実的です。

Unicode の範囲でざっくり捉える

正規表現で日本語を判定するときは、Unicode の範囲を使います。

ひらがな:\u3040-\u309F
カタカナ:\u30A0-\u30FF
漢字(CJK統合漢字):\u4E00-\u9FFF

これを組み合わせて、

/[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]/
JavaScript

と書くと、「ひらがな・カタカナ・漢字のどれか1文字」を表現できます。


「日本語を1文字でも含むか」を判定する基本ユーティリティ

一番よく使う形

まずは、「この文字列に日本語が1文字でも含まれているか?」を判定する関数です。

function containsJapanese(value) {
  if (value == null) return false;

  const s = String(value);

  if (s === "") return false;

  const re = /[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]/;

  return re.test(s);
}
JavaScript

ポイントを噛み砕きます。

null / undefined は即 false。
数値が来ても判定できるように String(value) で文字列化。
空文字は「日本語を含む」とはみなさず false。
正規表現で「ひらがな・カタカナ・漢字のどれか1文字でも含まれているか」をチェック。

動きのイメージ

containsJapanese("山田太郎");      // true(漢字)
containsJapanese("ヤマダタロウ");      // false(半角カナのみ)
containsJapanese("Yamada太郎");    // true(英字+漢字)
containsJapanese("Hello");         // false
containsJapanese("");              // false
JavaScript

「日本語が1文字でも混ざっているか?」を知るには、まずこれで十分です。


「日本語だけで構成されているか」を判定したい場合

「全部日本語か?」という少し厳しめのチェック

ときどき、

「この項目は“日本語だけ”にしたい(英数字や記号は入れたくない)」

という要件もあります。

その場合は、「日本語を含むか」ではなく、
「日本語以外の文字が混ざっていないか」を見る必要があります。

ただし、ここで一気に厳しくしすぎると、
スペースや句読点(。、)まで弾いてしまって、ユーザーがつらくなります。

なので、まずは「日本語+一部の記号は許可」という形で考えるのが現実的です。

例:ひらがな・カタカナ・漢字・スペース・句読点だけ許可

function isJapaneseOnly(value) {
  if (value == null) return false;

  const s = String(value).trim();

  if (s === "") return false;

  const re = /^[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\u3000\u3001\u3002\s]+$/;

  return re.test(s);
}
JavaScript

ここで許可しているのは、

ひらがな:\u3040-\u309F
カタカナ:\u30A0-\u30FF
漢字:\u4E00-\u9FFF
全角スペース:\u3000
全角読点・句点:\u3001\u3002
半角スペースなどの空白:\s

です。

動きのイメージ

isJapaneseOnly("山田太郎");          // true
isJapaneseOnly("山田 太郎");         // true(スペース許可)
isJapaneseOnly("山田太郎。");        // true(句点許可)
isJapaneseOnly("Yamada太郎");        // false(英字が混ざっている)
isJapaneseOnly("山田太郎123");       // false(数字が混ざっている)
JavaScript

「どこまで許可するか」は要件次第ですが、
考え方は「許可したい文字を [] の中に足していく」だけです。


半角カナや全角記号をどう扱うか

半角カナを「日本語扱い」にするかどうか

日本語環境だと、半角カナもよく出てきます。

"ヤマダタロウ"

これを「日本語として扱うかどうか」は、要件次第です。

もし「半角カナも日本語として扱いたい」なら、
正規表現に半角カナの範囲を足します。

半角カナの主な範囲は \uFF61-\uFF9F です。

const re = /[\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF\uFF61-\uFF9F]/;
JavaScript

これを containsJapanese に組み込めば、
半角カナも「日本語を含む」と判定されるようになります。

「日本語っぽい文字」をどこまで含めるかは設計の話

全角記号(「」「」など)や全角英数字も、
「日本語テキストの一部」として扱いたい場合があります。

ただし、ここを欲張りすぎると、
「何でもかんでも日本語扱い」になってしまうので、
まずは「ひらがな・カタカナ・漢字+必要なら半角カナ」くらいから始めて、
必要に応じて範囲を広げていくのがおすすめです。


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

「日本語を含んではいけない」項目のチェック

例えば、

ログインIDは英数字のみで、日本語は禁止。
商品コードは英数字と一部記号のみで、日本語は禁止。

という要件があるとき、

if (containsJapanese(code)) {
  showError("この項目には日本語を含めないでください。");
}
JavaScript

のように書くだけで、
「日本語が混ざっているかどうか」を簡単にチェックできます。

「日本語を含んでほしい」項目のチェック

逆に、

問い合わせ内容は日本語で書いてほしい。
自己紹介文は日本語を含んでいてほしい。

という要件なら、

if (!containsJapanese(message)) {
  showWarning("日本語で入力してください。");
}
JavaScript

のように、「日本語が1文字もない場合」に警告を出すことができます。

ここで大事なのは、
「禁止」だけでなく「推奨」のチェックにも使えるという視点です。


設計として意識してほしいこと

「含んでいるか」と「だけか」を関数レベルで分ける

日本語判定には、少なくとも2種類のニーズがあります。

日本語を1文字でも含んでいるか(containsJapanese)
日本語だけで構成されているか(isJapaneseOnly)

これを一つの関数に詰め込むと、
「この関数、何をどこまで見ているんだっけ?」と分かりづらくなります。

なので、

export function containsJapanese(value) { ... }
export function isJapaneseOnly(value) { ... }
JavaScript

のように、目的ごとに関数を分けるのがきれいです。

「どこまでを日本語とみなすか」をチームで決める

ひらがな・カタカナ・漢字だけか。
半角カナも含めるか。
全角記号も含めるか。

これは「正解」が一つではなく、
プロダクトの性質やユーザー層によって変わります。

だからこそ、

正規表現の範囲を一箇所(ユーティリティ)に集約しておく。
「日本語の定義」を変えたくなったら、そこだけ直せば全体に反映される。

という構造にしておくと、後からの変更にも強くなります。


ちょっとだけ手を動かしてみる

コンソールで、次のあたりを試してみてください。

containsJapanese("山田太郎");
containsJapanese("Yamada");
containsJapanese("Yamada太郎");

isJapaneseOnly("山田太郎");
isJapaneseOnly("山田 太郎");
isJapaneseOnly("Yamada太郎");
JavaScript

「どこからが true で、どこからが false になるか」を体で感じてみてください。

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

export function containsJapanese(value) { ... }
export function isJapaneseOnly(value) { ... }
JavaScript

のようなユーティリティを一つ置いて、
「日本語が混ざっているかどうかを見たいときは、必ずここを通す」
というルールにしてみてください。

それができた瞬間、あなたの検証処理は
「なんとなく if と正規表現を書いている状態」から
「意図を持って設計された日本語判定ユーティリティ」に、一段レベルアップします。

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