JavaScript Tips | 文字列ユーティリティ:検証 - 絵文字検出

JavaScript JavaScript
スポンサーリンク

絵文字検出で「何をしたいか」を先に決める

まずゴールをはっきりさせましょう。
ここでやりたいのは、文字列の中に「絵文字が含まれているかどうか」を判定するユーティリティを作ることです。

業務だと、例えばこういうニーズが出てきます。
ユーザー名やログインIDには絵文字を使わせたくない。
チャットやコメントでは絵文字OKだが、システム内部のコードには禁止したい。
「絵文字が含まれていたら別処理をしたい」(ログを分ける、サニタイズするなど)。

つまり、「絵文字を全部理解したい」ではなく、
「絵文字が1つでも混ざっているかどうかを検出したい」が現実的なゴールです。


絵文字検出が難しい理由をざっくり知っておく

絵文字検出は、メールアドレスや数字判定より一段難しいです。
理由はシンプルで、「絵文字の世界が広すぎる」からです。

同じ「顔」でも、肌の色バリエーションがあったり、
家族の絵文字のように複数のコードポイントの組み合わせだったり、
国旗の絵文字は「地域インジケータ」の組み合わせだったりします。

つまり、「絵文字はこの範囲です」と一発で書けるような単純な話ではありません。
それでも、実務では「完璧」より「そこそこちゃんと検出できる」ほうが大事なので、
現実的な落としどころのパターンを押さえていきます。


まずは「ざっくり絵文字を検出する」シンプル版

シンプルな絵文字検出関数

まずは、よく使われる絵文字の範囲をざっくりカバーする正規表現を使ったパターンです。
完璧ではありませんが、「絵文字が混ざっているかどうか」を見るには十分役に立ちます。

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

  const s = String(value);

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

  const re =
    /[\u203C-\u3299\uD83C-\uDBFF\uDC00-\uDFFF]/;

  return re.test(s);
}
JavaScript

ここでやっていることを噛み砕きます。
null / undefined は即 false。
数値が来ても判定できるように String(value) で文字列化。
空文字は false。
正規表現で「絵文字に使われがちなコードポイント」をざっくりカバーしている。

この正規表現は、ざっくり言うと次のような範囲を含みます。
記号系の一部(感嘆符など)。
絵文字が多く含まれるサロゲートペア領域(U+D83C〜U+DBFF など)。

細かい Unicode の説明は一旦置いておいて、「絵文字っぽいものが混ざっていたら true になる」くらいの理解でOKです。

動きのイメージ

containsEmoji("こんにちは");          // false
containsEmoji("こんにちは😊");        // true
containsEmoji("OKです👍");           // true
containsEmoji("★や♪などの記号");     // 場合によって true になることもある
containsEmoji("plain text only");    // false
JavaScript

「絵文字が混ざっているかどうか」をざっくり見るには、まずこのレベルで十分です。


「絵文字を含んでいたら弾きたい」ユーティリティ

絵文字禁止の入力チェック

例えば、ユーザーIDやシステム用コードなどで「絵文字禁止」にしたい場合は、
containsEmoji を使ってシンプルに弾けます。

function validateNoEmoji(value) {
  if (containsEmoji(value)) {
    return false;
  }
  return true;
}
JavaScript

実際のフォームでは、こんな感じで使えます。

const userId = userIdInput.value;

if (!validateNoEmoji(userId)) {
  showError("ユーザーIDに絵文字は使用できません。");
}
JavaScript

ここで大事なのは、「絵文字を完全に理解しているわけではない」ことを前提にしつつ、
「明らかに絵文字が混ざっているケース」をちゃんと拾う、というスタンスです。


もう少し真面目にやるなら「Unicode プロパティ」を使う

Unicode プロパティエスケープという武器

モダンな JavaScript(多くのブラウザの新しめの環境)では、
正規表現で Unicode の「プロパティ」を使うことができます。

例えば、\p{Emoji} のように書くと、「Emoji プロパティを持つ文字」を表現できます。
これを使うと、絵文字検出がかなり素直に書けます。

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

  const s = String(value);

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

  const re = /\p{Emoji}/u;

  return re.test(s);
}
JavaScript

ここでのポイントは、/u フラグを付けていることです。
Unicode モードで正規表現を解釈することで、\p{Emoji} のようなプロパティ指定が使えるようになります。

ただし対応環境に注意

この書き方はとてもきれいですが、
古いブラウザや一部の実行環境ではサポートされていないことがあります。

業務システムで使う場合は、
「ターゲット環境が Unicode プロパティエスケープに対応しているか」を確認したうえで採用するのが安全です。


絵文字を「検出する」だけでなく「取り除く」ユーティリティ

絵文字を削除して保存したいケース

ときどき、「絵文字を含んでいてもエラーにはしないが、保存するときは絵文字を落としたい」という要件もあります。
ログや外部システム連携で、絵文字が文字化けの原因になる場合などです。

containsEmoji を応用して、「絵文字を削除する」関数も作れます。

シンプル版の例です。

function removeEmoji(value) {
  if (value == null) return "";

  const s = String(value);

  const re =
    /[\u203C-\u3299\uD83C-\uDBFF\uDC00-\uDFFF]/g;

  return s.replace(re, "");
}
JavaScript

これで、絵文字っぽい文字を空文字に置き換えます。

removeEmoji("OKです👍");      // "OKです"
removeEmoji("こんにちは😊");  // "こんにちは"
JavaScript

完璧ではありませんが、「絵文字が原因で文字化けするのを避けたい」という目的には十分役立ちます。


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

「完璧な絵文字検出」を目指さない

絵文字は仕様も広く、追加も多く、
「全部を正規表現でカバーする」のは現実的ではありません。

だからこそ、設計として大事なのは次の割り切りです。
絵文字を完全に理解するのではなく、「絵文字が混ざっている可能性が高い文字」を検出する。
「検出できなかった絵文字があっても、致命的な問題にならない設計」にしておく。

例えば、ユーザーIDのような「絶対に絵文字を入れたくない」項目では、
絵文字検出に加えて「許可する文字種を限定する」(英数字のみなど)という二重の防御をしておくと安心です。

「検出」と「禁止/削除」の責務を分ける

containsEmoji は「絵文字が含まれているかどうか」を教えてくれるだけの関数です。
それをどう扱うか(エラーにするのか、警告にするのか、削除するのか)は、別のレイヤーの責務です。

例えば、こう分けておくときれいです。
containsEmoji … 絵文字が含まれているかどうかを判定する。
validateNoEmoji … 絵文字が含まれていたら false を返すバリデーション。
removeEmoji … 絵文字を削除した文字列を返す。

責務を分けておくと、
「この関数は何をするためのものか」が明確になり、テストもしやすくなります。


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

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

containsEmoji("こんにちは");
containsEmoji("こんにちは😊");
containsEmoji("OKです👍");
removeEmoji("OKです👍");
removeEmoji("絵文字なしのテキスト");
JavaScript

「どこからが true で、どこからが false になるか」
「絵文字がどう削除されるか」を体で感じてみてください。

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

export function containsEmoji(value) { ... }
export function validateNoEmoji(value) { ... }
export function removeEmoji(value) { ... }
JavaScript

のようなユーティリティを一つ置いて、
「絵文字を気にしたいときは必ずここを通す」というルールにしてみてください。

それだけで、あなたの文字列検証は
場当たり的な「なんか変な文字が入ってるぞ?」対応から、
意図を持って設計された「絵文字検出ユーティリティ」に一段レベルアップします。

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