I found this awesome way to detect emojis using a regex that doesn't use "huge magic ranges" by using a Unicode property escape:
console.log(/\p{Emoji}/u.test('flowers ๐ผ๐บ๐ธ')) // true
console.log(/\p{Emoji}/u.test('flowers')) // false
But when I shared this knowledge in this answer, @Bronzdragon noticed that \p{Emoji}
also matches numbers! Why is that? Numbers are not emojis?
console.log(/\p{Emoji}/u.test('flowers 123')) // unexpectdly true
// regex-only workaround by @Bonzdragon
const regex = /(?=\p{Emoji})(?!\p{Number})/u;
console.log(
regex.test('flowers'), // false, as expected
regex.test('flowers 123'), // false, as expected
regex.test('flowers 123 ๐ผ๐บ๐ธ'), // true, as expected
regex.test('flowers ๐ผ๐บ๐ธ'), // true, as expected
)
// more readable workaround
const hasEmoji = str => {
const nbEmojiOrNumber = (str.match(/\p{Emoji}/gu) || []).length;
const nbNumber = (str.match(/\p{Number}/gu) || []).length;
return nbEmojiOrNumber > nbNumber;
}
console.log(
hasEmoji('flowers'), // false, as expected
hasEmoji('flowers 123'), // false, as expected
hasEmoji('flowers 123 ๐ผ๐บ๐ธ'), // true, as expected
hasEmoji('flowers ๐ผ๐บ๐ธ'), // true, as expected
)
#
and0-9
areEmoji
characters with a text representation by default, per the Unicode Standard. โ Etti/\p{Extended_Pictographic}/u
regex to match emojis except for some keycap base characters that are still emojis. โ Etti