如何将视觉相似的Unicode字符转为ASCII?能否复用VSCode相关库?
复用VSCode的同形字符处理解决Unicode规避问题
VSCode用来检测替换歧义Unicode字符的核心逻辑,就是针对视觉相似的字符做映射,完全适配你过滤程序的需求。你可以直接用VSCode官方提供的npm包来实现:
1. 用@vscode/unicode-utilities实现字符归一化
这个包是VSCode内部依赖的Unicode工具集,内置了同形字符的视觉映射规则。
安装依赖
npm install @vscode/unicode-utilities
示例代码
import { UnicodeUtilities } from '@vscode/unicode-utilities'; function normalizeHomoglyphs(str) { let output = ''; for (const char of str) { // 尝试获取字符的视觉等效拉丁字母,没有则保留原字符 const replacement = UnicodeUtilities.getHomoglyphReplacement(char); output += replacement || char; } return output; } // 测试你的示例字符串 const s = "FRЕЕ DISСОRD NIТRO"; const normalizedStr = normalizeHomoglyphs(s); console.log(normalizedStr); // 输出: "FREE DISCORD NITRO"
这段代码会把西里尔字母Е、С、О、Т精准替换成视觉一致的拉丁字母,处理后的字符串就能正常匹配DISCORD这类关键词了。
2. 自定义映射规则(可选)
如果默认映射覆盖的字符不够,你可以参考VSCode源码里的同形字符规则,自己扩展映射表:
// 自定义额外的视觉相似字符映射 const customMap = { 'а': 'a', 'е': 'e', 'і': 'i', // 按需添加更多字符对 }; function normalizeWithCustom(str) { let output = ''; for (const char of str) { const vscodeReplace = UnicodeUtilities.getHomoglyphReplacement(char); const customReplace = customMap[char]; output += vscodeReplace || customReplace || char; } return output; }
为什么这个方案比unidecode/anyascii靠谱?
unidecode和anyascii的核心是音译,比如会把西里尔的С转成S,但VSCode的逻辑是完全基于视觉相似性做映射,正好解决你遇到的过滤失效问题,而且复用的是VSCode已经验证过的成熟规则,不用自己从零整理庞大的同形字符表。
内容的提问来源于stack exchange,提问作者SomeCoder
相关产品推荐
相关产品推荐

