为什么Unicode表情符号属性转义与数字匹配? [英] Why do Unicode emoji property escapes match numbers?
本文介绍了为什么Unicode表情符号属性转义与数字匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我发现了一种很棒的检测emoji表情符号的方法,它使用的正则表达式没有使用巨大的魔术范围&通过使用Unicode property escape:
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">console.log(/p{Emoji}/u.test('flowers 🌼🌺🌸')) // true
console.log(/p{Emoji}/u.test('flowers')) // false
p{Emoji}
也匹配数字!为什么会这样呢?数字不是表情符号吗?
数据-lang="js"数据-隐藏="假"数据-控制台="真"数据-巴贝尔="假">
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
)
推荐答案
根据this post,Digtis,#
,*
,zwj和其他一些字符包含Emoji
属性设置为是,这意味着数字被视为有效的emoji字符:
0023 ; Emoji_Component # 1.1 [1] (#️) number sign
002A ; Emoji_Component # 1.1 [1] (*️) asterisk
0030..0039 ; Emoji_Component # 1.1 [10] (0️..9️) digit zero..digit nine
200D ; Emoji_Component # 1.1 [1] () zero width joiner
20E3 ; Emoji_Component # 3.0 [1] (⃣) combining enclosing keycap
FE0F ; Emoji_Component # 3.2 [1] () VARIATION SELECTOR-16
1F1E6..1F1FF ; Emoji_Component # 6.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
1F3FB..1F3FF ; Emoji_Component # 8.0 [5] (🏻..🏿) light skin tone..dark skin tone
1F9B0..1F9B3 ; Emoji_Component # 11.0 [4] (🦰..🦳) red-haired..white-haired
E0020..E007F ; Emoji_Component # 3.1 [96] (..) tag space..cancel tag
例如1
是数字,但与U+FE0F
和U+20E3
字符组合:1️⃣:
console.log("1uFE0Fu20E3 2uFE0Fu20E3 3uFE0Fu20E3 4uFE0Fu20E3 5uFE0Fu20E3 6uFE0Fu20E3 7uFE0Fu20E3 8uFE0Fu20E3 9uFE0Fu20E3 0uFE0Fu20E3")
如果要避免匹配数字,请使用Extended_Pictographic
Unicode类别类:
扩展象形文字字符包含除某些Emoji_组件之外的所有Emoji字符。
所以,您可以使用/p{Extended_Pictographic}/gu
来匹配大多数表情包,或者使用/p{Extended_Pictographic}/u
来测试单个表情包是否合适,或者使用/[p{Extended_Pictographic}u{1F3FB}-u{1F3FF}u{1F9B0}-u{1F9B3}]/u
将表情包和浅色皮肤匹配到深色皮肤模式字符,或者使用/[p{Extended_Pictographic}u{1F3FB}-u{1F3FF}u{1F9B0}-u{1F9B3}]/u
匹配红发到白发字符:
const regex_emoji = /[p{Extended_Pictographic}u{1F3FB}-u{1F3FF}u{1F9B0}-u{1F9B3}]/u;
console.log( regex_emoji.test('flowers 123') ); // => false
console.log( regex_emoji.test('flowers 🌼🌺🌸') ); // => true