2024-08-14 探索JS中的神秘角色:零宽字符

今天在维护原生jQuery项目时,有一个DataTable类库写的导出操作,在导出任务编号时总会出现后面的两位数字自动改变成填充成0的bug,查看了官方文档,提前打印并没有看出数据有什么问题,我在任务编号的后面添加了任意字符串后自动改变填充0的情况不会出现了,可是自行添加编号,并不符合逻辑,想着能不能加一个空字符串或空格字符串来解决,尝试之后还是会变成原来的问题,于是就想到能不能加一个肉眼看不见但真实存在的字符——零宽字符,尝试之后成功了,暂时就先用这种解决方案

oTable.cell(index, 1).data(data['event_code'] + "\u200B")
  • 在控制台还是能看出端倪的

零宽字符是什么

零宽字符,顾名思义,是指那些宽度为零的字符,它们在屏幕上不显示任何内容,但会占用字符串的长度。常见的零宽字符包括ZERO WIDTH SPACE(U+200B)和ZERO WIDTH NON-JOINER(U+200C)等。这些字符在文本处理、数据交换等场景中可能会不经意间被引入,给后续的数据解析和展示带来麻烦。

零宽字符的特性

  1. 非捕获性
    零宽字符的一个显著特性是非捕获性。在正则表达式中,虽然可以通过某些模式匹配到零宽字符,但这些字符本身并不被捕获或替换。这意味着,即便我们成功匹配到了零宽字符,也无法直接通过替换操作将其从字符串中移除。

  2. 不吃字符
    另一个重要特性是“不吃字符”,即零宽字符不占据查找位置,它们只是作为匹配的条件存在,而不实际占用字符串的任何位置。这一特性使得零宽字符在正则表达式的查找和替换过程中显得尤为特殊。

零宽字符的实例与排查

  1. 实例场景

假设我们在开发一个Web应用时,从前端向后端传输了一段文本数据。在后端解析这段数据时,发现字符串的长度比预期的要长,但查看内容却发现并无异常。这时,很可能是字符串中包含了零宽字符。

直接复制的账号无法登录问题,可能账号中包含了零宽字符

其他用途,数据加密,版权保护等……

  1. 排查方法
    为了确定字符串中是否包含零宽字符,我们可以使用JavaScript的charCodeAt()方法遍历字符串的每个字符,检查其Unicode编码。对于ZERO WIDTH SPACE,其编码为U+200B(即十进制中的8203);而对于ZERO WIDTH NON-JOINER,其编码为U+200C(十进制中的8204)。
for (let i = 0; i < str.length; i++) {  
    if (str.charCodeAt(i) === 8203 || str.charCodeAt(i) === 8204) {  
        console.log('找到零宽字符', str[i], '在位置', i);  
    }  
}

处理零宽字符

一旦确认了字符串中存在零宽字符,我们就需要采取措施将其移除。由于零宽字符的非捕获性和不吃字符特性,直接使用字符串的替换方法(如replace())可能无法达到预期效果。这时,我们可以利用正则表达式进行全局替换。

// 移除ZERO WIDTH SPACE  
str = str.replace(/\u200b/g, '');  
  
// 移除ZERO WIDTH NON-JOINER  
str = str.replace(/\u200c/g, '');  
  
// 或者,如果你不确定具体是哪种零宽字符,可以一次性移除所有可能的零宽字符  
str = str.replace(/[\u200b-\u200d\uFEFF]/g, '');

总结

零宽字符虽然看似不起眼,但在实际开发中却可能引发一系列问题。了解零宽字符的特性,掌握其排查和处理方法,解决问题时多一条思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值