使用正则过滤特殊字符时Telegram数字emoji未被删除如何解决
问题根因
- 1️⃣这类数字键帽emoji由「ASCII数字 + emoji变体选择符(U+FE0F) + 组合键帽标记(U+20E3)」三个Unicode码点组合而成,原有正则的
\d会匹配到emoji前缀的ASCII数字,导致多余的1、2、6等数值被提取。 - 末尾的4️⃣未被匹配是字符串末尾编码边界的偶然情况,不代表规则生效,只要存在数字前缀的emoji就有概率出现误匹配。
解决方案
方案1:Unicode属性转义清除所有emoji后匹配(推荐)
利用ES2018支持的Unicode属性转义,先移除所有emoji类字符,再执行原有匹配逻辑,可覆盖所有类型的emoji,后续新增emoji也无需调整规则:
const text = '1️⃣Hi =) 1.This regex removes 2️⃣all special 6️⃣characters like this !@$#%^&*()_+=~`/\><.⚠️4️⃣' // 清除所有emoji相关字符 const pureText = text.replace(/(\p{Extended_Pictographic}|\p{Emoji_Modifier}|\p{Emoji_Component})/gu, '') const result = pureText.toUpperCase().match(/[a-z]+|\d+(?:\.\d+)?/gi) .map(m => isNaN(m) ? m : +m)
运行后输出和期望完全一致。
方案2:修改原有正则增加负向预查
如果不想改动原有逻辑,只需要给数字匹配规则增加负向预查,排除后面跟着emoji修饰符的数字即可:
const text = '1️⃣Hi =) 1.This regex removes 2️⃣all special 6️⃣characters like this !@$#%^&*()_+=~`/\><.⚠️4️⃣' const result = text.toUpperCase().match(/[a-z]+|\d+(?:\.\d+)?(?![\uFE0F\u20E3])/gi) .map(m => isNaN(m) ? m : +m)
该方案仅针对数字键帽类emoji有效,适合不需要处理其他类型emoji的场景。
内容的提问来源于stack exchange,提问作者dumpAndDie
相关产品推荐
相关产品推荐

