絵文字検出で「何をしたいか」を先に決める
まずゴールをはっきりさせましょう。
ここでやりたいのは、文字列の中に「絵文字が含まれているかどうか」を判定するユーティリティを作ることです。
業務だと、例えばこういうニーズが出てきます。
ユーザー名やログイン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のようなユーティリティを一つ置いて、
「絵文字を気にしたいときは必ずここを通す」というルールにしてみてください。
それだけで、あなたの文字列検証は
場当たり的な「なんか変な文字が入ってるぞ?」対応から、
意図を持って設計された「絵文字検出ユーティリティ」に一段レベルアップします。

