はじめに
タイトルにある通りJSで絵文字を検知することについて記載します。
とはいえ、他にも同じように『絵文字検知』は記載している人いるので、今回はタブレット(Swift)と同じように検知するを目標に話を進めたいと思います。
身近なニーズとしてWebページ側と、タブレットの両方から登録できるシステムがありタブレット側では絵文字の入力チェックが入っている。かたやWeb画面側には絵文字はノーチェックと言う事象がひとまず止血はしたいけど、タブレットと同じにしたいと言う要望を対応するのが今回の目的ではやっていこう。
Step
ひとまず以下の手順で進行する
- タブレット側でどのように検知しているのか(Swift)のお話
- JS側でどのように実現するのか?(JavaScript)
- まとめ
タブレット側でどのように検知しているのか(Swift)のお話
- タブレット側のソースを確認したところSwift5から出ている「isEmoji」を使って居そうということまではわかりました。>参考:Swift 5から文字列から絵文字を検出するのが容易になりました
脱線するけど、絵文字って国際標準の言葉になったの?すごい日本の文化!『isEmoji!』だからね!
https://www.unicode.org/reports/tr51/tr51-27.html#Introduction
- あとSwiftのバージョンについても念のために確認
バージョンはSwift5でした。
これらの情報を基にSwift5時点でのisEmojiが何を絵文字としているのかを確認していきたいと思います!(これでJS側で制御すべきものが見えてくるはず!)
で、たどり着いたのがこちらの記事
下の方を確認していくと当時のUnicodeのサイトへ
Unicode12.0.0で扱っていた絵文字の一覧はこちら
つまり上記の絵文字を検知できればOK
JS側でどのように実現するのか?(JavaScript)
やること
- 通常の文字(例: 数字「3」やアルファベットなど)は検出しない。
- 2バイトの絵文字、4バイトの絵文字、ZJWを含む複合絵文字に対応。
- 絵文字が含まれるかどうかを判定し、含まれる絵文字を抽出できる。
function extractEmojis(text) {
// 絵文字を検出する正規表現 (通常文字や数字を除外)
const emojiRegex = /(?:[\uD83C-\uDBFF][\uDC00-\uDFFF]|\u2600-\u26FF|\u2700-\u27BF|\u24C2|\uD83C[\uDD70-\uDDFF\uDE01-\uDEFF\uDF00-\uDFFF]|\uD83D[\uDC00-\uDDFF\uDE00-\uDEFF]|\uD83E[\uDD00-\uDDFF]|\u200D)+/g;
// マッチした絵文字のリストを返す
return text.match(emojiRegex) || [];
}
function containsEmoji(text) {
return extractEmojis(text).length > 0;
}
// テストコード
const testStrings = [
"こんにちは3😀🌟👨👩👧👦", // 絵文字と通常の数字を含む
"123", // 数字のみ
"✨文字✈️", // 絵文字と日本語
"🍎🍏🍊", // 絵文字のみ
];
testStrings.forEach((str) => {
console.log(`テキスト: "${str}"`);
console.log(`Contains Emoji: ${containsEmoji(str)}`);
console.log(`Extracted Emojis: ${extractEmojis(str)}`);
console.log("-----------");
});
コードの解説
1. 正規表現のポイント
-
[\uD83C-\uDBFF][\uDC00-\uDFFF]
:4バイト絵文字(サロゲートペア)を検出。 -
[\u2600-\u26FF]
:2バイトで表現される絵文字(例: ☀️, ☔)。 -
[\u2700-\u27BF]
:Dingbatsや簡単な記号絵文字 -
[\u200D]
:Zero Width Joiner (ZJW) を考慮し、複合絵文字を1つの単位として扱う -
[\u24C2]
:特定の囲み文字の絵文字。
2. extractEmojis 関数
- 入力文字列中に一致する絵文字をすべて抽出し、配列として返します。
- 一致する絵文字がなければ空配列を返します。
3. containsEmoji 関数
- 絵文字が1つでも含まれていれば true を返し、含まれなければ false を返します。
実行結果
テキスト: "こんにちは3😀🌟👨👩👧👦"
Contains Emoji: true
Extracted Emojis: ["😀", "🌟", "👨👩👧👦"]
-----------
テキスト: "123"
Contains Emoji: false
Extracted Emojis: []
-----------
テキスト: "✨文字✈️"
Contains Emoji: true
Extracted Emojis: ["✨", "✈️"]
-----------
テキスト: "🍎🍏🍊"
Contains Emoji: true
Extracted Emojis: ["🍎", "🍏", "🍊"]
-----------
まとめ
JSをつかって・・・とかいって書いてみたらなんてことはない文字コードと正規表現の話で終わった気がする。
とは言えやったことないことだったし、タブレットと同じ(Swift5で対応している)絵文字を対象と言うアプローチのおかげでUnicodeについても少し知識が増えた気がするから今回は面白かった。
ではでは👋