空格符号复制空白代码
昨天下午,空格空白同事小陈发来一个Excel表格,符号复制说编号那一列怎么都对不齐。代码我点开一看,空格空白数字前面全带着一个看不见的符号复制字符。他试过删空格、代码用TRIM函数,空格空白都没用。符号复制那个字符不是代码空格,是空格空白Unicode里的U+00A0,叫不换行空格。符号复制复制到浏览器地址栏里,代码它显示成% C2%A0,空格空白肉眼根本分辨不出来。符号复制 这类空白符号比想象中多得多。代码普通空格是U+0020,键盘上敲一下就有。不换行空格U+00A0常见于网页复制的内容,它会阻止浏览器在該处换行。还有U+2002到U+200B这一串,分别叫en空格、em空格、窄空格、零宽空格。零宽空格最阴险,它不占任何宽度,但会让两个看起来挨着的字符被程序识别为不同内容。 我见过一个真实案例。某公司做用户注册,前端校验用户名长度时用JavaScript的length属性。有个用户输入了“张三”,看起来两个字,提交却提示“用户名至少3个字符”。排查半天才发现,用户是从某个PDF里复制过来的,两个字中间夹了一个零宽空格。length算出来是3,人眼看到的却是2。这种bug测试阶段很难复现,因为没人会故意去复制一个零宽空格。 空白代码的复制粘贴在编程里更常见。HTML里写 有次帮朋友处理数据清洗,他从某平台导出的CSV文件,商品名称列里混了大量U+00A0。用pandas读进来,str.strip()去不掉。得先用 浏览器地址栏也是个重灾区。有人分享链接时,从聊天软件里复制,末尾带了一个零宽空格。粘贴到浏览器里,页面打不开,提示404。肉眼检查URL完全正常,因为那个字符根本不显示。Chrome的开发者工具里,Network面板能看到实际请求的URL,末尾多了一个 怎么快速识别这些看不见的东西?几个办法。用VS Code打开文件,装个插件叫“Highlight Bad Chars”,它会用彩色背景标出所有非ASCII空白字符。在线工具里,我常用 写代码时主动防御比事后排查省事。处理用户输入,第一件事就是规范化空白字符。Python里可以用 空白符号本身不是bug,它们是Unicode标准的一部分,各有各的用途。问题出在复制粘贴这个动作上——你永远不知道剪贴板里夹带了什么。下次遇到“看起来一样但程序说不等”的情况,先别怀疑逻辑,把字符串打印成repr看看,大概率是某个看不见的字符在作怪。 就是插入一个不换行空格,四个字母加一个分号,渲染出来就是一个空白。CSS里用content: "\200B"可以生成零宽空格,用来做某些排版微调。Python里\u200b写在字符串里,打印出来什么都看不到,但len()会把它算进去。我习惯在调试字符串时加一行print(repr(s)),repr会把不可见字符显示成转义序列,一眼就能看出问题。str.replace('\xa0', ' ')替换成普通空格,再strip。他之前手动改了二十几行,改到眼睛发酸。知道原理后,一行代码搞定。%E2%80%8B。这种问题查起来很折磨人,因为你的第一反应是链接失效了,不会想到是空白字符在捣乱。unicode-table.com,把可疑文本粘进去,它会把每个字符的码点列出来。命令行下,cat -A file.txt会把制表符显示成^I,行尾显示成$,不换行空格显示成M-BM- 。虽然看着乱,但至少能定位。unicodedata.normalize('NFKC', s),它会把各种兼容字符转成标准形式,U+00A0会变成普通空格。JavaScript里写个正则s.replace(/[\u00A0\u2000-\u200B]/g, ' '),把常见的不速之客统一替换掉。数据库存之前做一次清洗,比存进去之后再捞出来洗要轻松得多。
-
上一篇
-
下一篇