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
)