piapia123
zh

文本体检

文本

所有处理都在浏览器本地完成,数据不上传服务器

输入
把文件拖到这里可直接载入
输出

「这段代码看起来一模一样,为什么报错?」「这个变量名我复制过来的,为什么找不到?」「这份 CSV 明明有表头,为什么第一列的名字不对?」—— 这三个问题的答案通常是同一个:文本里混进了看不见的东西。 它们分成三类,这里分开报: · 不可见字符 —— 零宽空格、BOM、方向控制符、不间断空格、全角空格。每一处都给位置:一个零宽空格出现在第 3 个字和第 300 个字,处理方式完全不同。 · 易混字符 —— 西里尔 / 希腊里与拉丁字母同形的那些(西里尔的 `а` 与拉丁的 `a`)。这是「域名钓鱼」(`раypal.com` 与 `paypal.com` 肉眼一模一样,却是不同的域名)与「代码里混进另一个字母表导致对不上」的常见原因。⚠️ 只报跨文字系统的形近:全角 `a` 与半角 `a` 同属拉丁字母,只是宽度形式不同,那归 NFKC 规范化管,不算同形字 —— 否则中文文本里夹几个全角字母就会被满屏误报。 · 编码形式 —— 规范化形式、行尾是否混合、字数怎么数。 ⚠️ `é` 有两种写法:一个码位(U+00E9),或者 `e` 加组合尖音符(两个码位)。两者肉眼完全一样,但字节不同、比较也不相等。macOS 的文件名用前者之外的另一种形式存,而多数编程语言按规范形式比较 —— 这就是「同一个文件名在两台机器上对不上」的根源。

功能

  • 找出全部不可见字符并给出位置:零宽空格/连接符、BOM、软连字符、方向覆盖符、不间断空格、全角空格等 30 种
  • 找出易混字符(西里尔 / 希腊里与拉丁同形的字母),指出它真正是什么、又看起来像哪个字母
  • 把易混字符在原文里标出来,与不可见字符用同一套 `⟦…⟧` 记号:`раypal` → `⟦U+0440 Cyrillic→p⟧⟦U+0430 Cyrillic→a⟧ypal`,一眼看出第几个字母其实是西里尔文
  • 按书写系统统计字符数 —— 混排时一眼看出多了哪一套字母表
  • NFC / NFD / NFKC / NFKD 四种规范化形式逐项检查,并说明「已经是 NFC 但不是 NFKC」意味着什么
  • 行尾检测(LF / CRLF / CR),混合时单独提示 —— 它的表现是某个脚本报一句位置很奇怪的语法错
  • 四种字数并列:字形簇、码位、UTF-16 码元(JavaScript 的 length)、UTF-8 字节
  • 可选把不可见字符与易混字符替换成 `⟦U+200B⟧` / `⟦U+0430 Cyrillic→a⟧` 这样的标记,便于粘去别处核对

使用方法

  1. 把那段文本粘进来
  2. 看「不可见字符」与「易混字符」两组里有没有东西
  3. 需要的话打开「标出可疑字符」,把标记后的文本复制去排查

常见问题

一个 emoji 为什么有四种「长度」?
因为「长度」这个词有四种数法。`👍` 在人的眼里是 1 个字(字形簇),在 Unicode 里是 1 个码位,在 JavaScript 的字符串里是 2 个码元(代理对),在 UTF-8 里是 4 个字节。要不要出错的场合用错数法,就是经典的「截断把 emoji 切成两半」。而 `👨‍👩‍👧` 更极端:1 个字、5 个码位、8 个码元。
零宽空格是怎么进来的?
最常见的三个来源:从网页上复制文本时带上了排版用的零宽字符;iOS 与 macOS 的软键盘在某些输入法下会插入;以及从聊天软件转发时被加了方向控制符。它们不影响显示,却会被当成标识符的一部分 —— 于是「看起来一样的变量名」编译不过。
「已经是 NFC 但不是 NFKC」是什么意思?
NFC 与 NFKC 的差别是后者还会做兼容分解:全角字母数字、连字(fi)、上标(²)会被换成普通写法。所以一份文本可以既是「规范等价的」又含有全角字符 —— 而全角 `a` 与半角 `a` 在搜索、比较、当作标识符时都不等价。要做数据清洗时该用 NFKC;只是想让重音符号统一时用 NFC 就够。
行尾混合为什么会造成语法错?
因为多数语言的解析器把换行当空白,但某些工具(旧版的 Shell 脚本、Makefile、部分模板引擎)会把 CR 当成内容的一部分。于是 ` ` 里那个多出来的 CR 跑到字符串或变量名末尾,报错的位置看起来毫无道理。Git 的 `autocrlf` 在不同机器上设置不一致,是这种文件最常见的来源。
为什么全角字母、日文的「ー」不会被报成易混字符?
因为判定是保守的:只有形近的那个字符属于另一套文字系统时才算可疑。西里尔的 `а` 长得像拉丁的 `a`(西里尔 ≠ 拉丁)、希腊的 `Ο` 长得像拉丁的 `O`(希腊 ≠ 拉丁),这些才是真正的同形字钓鱼手法。而全角 `a` 与半角 `a` 同属拉丁字母,只是宽度形式不同 —— 那是规范化问题(NFKC 会处理,本工具在「规范化形式」一组里另有提示),不是钓鱼问题;日文的 `ー` 也只是形近某个符号,不构成跨系统同形。宁可少报,也不要把中文、日文里正常的全角字符淹成一屏报警 —— 那样真正该看的西里尔字母反而会被淹掉。代价是:整段真正的俄文或希腊文文本里,字母也会被标出来,但那种文本在本工具的目标场景里极少。

相关工具