如何忽略双向字符(Bidi)校验字符串相等性?
忽略双向文本控制字符比较字符串相等性
你遇到的问题是因为字符串中包含了Unicode双向文本控制字符(\u202B右到左嵌入、\u202C弹出格式化),这类字符仅影响文本渲染方向,视觉上和普通字符串一致,但实际属于字符串的一部分,导致直接比较不相等。要实现忽略这类字符的相等校验,核心思路是先移除字符串中的双向控制字符,再进行比较。
方案一:精准过滤双向控制字符
直接匹配所有双向文本相关的控制字符并移除,这类字符的Unicode范围包括:
- LRE(\u202A)、RLE(\u202B)、PDF(\u202C)、LRO(\u202D)、RLO(\u202E)
- LRI(\u2066)、RLI(\u2067)、FSI(\u2068)、PDI(\u2069)
实现代码:
function stripBidiControls(str) { const bidiChars = /[\u202A-\u202E\u2066-\u2069]/g; return str.replace(bidiChars, ''); } // 测试你的示例 const a = "\u202B" + "hi" + "\u202C"; console.log(stripBidiControls(a) === 'hi'); // true console.log(stripBidiControls(a) == 'hi'); // true
方案二:移除所有格式控制字符(ES2018+)
如果你的运行环境支持ES2018及以上的Unicode属性类,可以用\p{Cf}匹配所有Unicode格式控制字符(包含双向控制字符、零宽空格等),一次性清理:
function stripFormatControls(str) { // \p{Cf} 匹配Unicode"格式控制"类别下的所有字符 return str.replace(/\p{Cf}/gu, ''); } console.log(stripFormatControls(a) === 'hi'); // true
注意:这个方案会移除所有格式控制字符,如果你只需要忽略双向控制字符,方案一更精准。
额外提示
- 建议把清理逻辑封装成工具函数,方便多处调用。
- 测试时要覆盖所有可能的双向控制字符场景,避免遗漏导致比较失效。
内容的提问来源于stack exchange,提问作者sir-haver
相关产品推荐
相关产品推荐

