原来空格不止空格、全角空格和 Tab 制表符,怎么还有这么多种空格啊。如果你也遇到了空格处理的问题,建议看看这篇空格的认识。
各种空格
起因是我前一阵正在用 Python 处理各种数据文件,但当我处理 txt 数据格式的时候出现了大量的错误,这些错误无一例外都指向的空格的问题。
我截取了一部分 txt 数据的截图。好家伙,空格、制表符、全角空格、零宽空格、无中断空格等各种样式应有尽有,怪不得我逐行读取的时候经常出错。因为我处理的数据 txt 格式大都是 UTF-8 编码格式,于是我就查了下 Unicode 标准。
在 Unicode 标准中,定义了多种空格字符,用于不同的语言和格式。以下是一些常见的空格字符及其 Unicode 编码:
Unicode: U+0020 Description: 标准半角空格。 不间断空格 (Non-breaking Space) Unicode: U+00A0 Description: 用于保持文本中单词之间的空格不被断开。 全角空格 (Full-width Space) Unicode: U+3000 Description: 用于东亚文字,与全角字符宽度相同。 零宽度空格 (Zero Width Space) Unicode: U+200B Description: 用于控制文本布局,不可见。 零宽度非换行空格 (Zero Width No-break Space) Unicode: U+FEFF Description: 也称为字节顺序标记(Byte Order Mark, BOM),在文本流的开始处使用。 零宽度连字 (Zero Width Joiner) Unicode: U+200D Description: 用于连接某些字符,如阿拉伯文字。 空格 (Space) Unicode: U+1680 Description: 也称为Ogham空格标记,用于Ogham脚本。 窄空格 (Narrow No-Break Space) Unicode: U+202F Description: 比普通空格窄,不换行。 半角空格 (Medium Mathematical Space) Unicode: U+205F Description: 用于数学公式,比普通空格宽。 六分空格 (Six-per-em Space) Unicode: U+2002 Description: 约等于半个普通空格的宽度。 四分空格 (Four-per-em Space) Unicode: U+2005 Description: 约等于四分之一个普通空格的宽度。 数字空格 (Figure Space) Unicode: U+2007 Description: 用于数字之间的空格,与数字宽度相同。
这些空格字符在文本处理和排版中有着不同的用途。例如,不间断空格用于确保网址和电子邮件地址在文本中不被断开;全角空格则用于匹配日文、中文等语言中的全角字符宽度等。
编码与空格
ASCII
- 定义:最早的字符编码标准,仅使用 7 位表示 128 个字符,包括英文字母、数字、基本符号和控制字符。
- 空格:仅包含普通空格 (
U+0020
),没有其他特殊空格。
GBK
- 定义:主要用于简体中文的编码,向下兼容 ASCII,扩展了汉字和全角字符(包括标点和空格)。
- 空格:普通空格 (
U+0020
) 和全角空格 (U+3000
) 都被包含,不包含 Unicode 的其他特殊空格字符。
UTF-8
- 定义:Unicode 的一种可变长度编码方式,广泛使用,向后兼容 ASCII,编码范围覆盖全球所有字符。
- 空格:能表示 Unicode 定义的所有空格字符(如普通空格、不间断空格、零宽度空格等)。普通空格 (
U+0020
) 在 UTF-8 中为单字节,其他空格字符编码长度根据其 Unicode 值不同。
Unicode
- 定义:全球通用的字符集标准,给每个字符分配唯一的编码(Code Point)。
- 空格:定义了所有类型的空格,包括普通空格 (
U+0020
)、全角空格 (U+3000
)、不间断空格 (U+00A0
)、零宽度空格 (U+200B
) 等。
各种空格与这些编码的关系整理如下表:
空格类型 | ASCII | GBK | UTF-8 | Unicode |
---|---|---|---|---|
普通空格 (U+0020 ) | ✅ | ✅ | ✅ | ✅ |
全角空格 (U+3000 ) | ❌ | ✅ | ✅ | ✅ |
不间断空格 (U+00A0 ) | ❌ | ❌ | ✅ | ✅ |
零宽度空格 (U+200B ) | ❌ | ❌ | ✅ | ✅ |
窄空格 (U+202F ) | ❌ | ❌ | ✅ | ✅ |
数字空格 (U+2007 ) | ❌ | ❌ | ✅ | ✅ |
正则匹配空格
知道原因了,就用正则匹配去解决:
[\p{Zs}\u200B\uFEFF\u2000-\u200A\u202F\u205F\u3000]
- \p{Zs}: 匹配所有的标准空格字符;
- \u200B: 零宽度空格;
- \uFEFF: 零宽度非换行空格(字节顺序标记);
- \u2000-\u200A: 范围匹配其他宽度的空格字符(如六分空格、四分空格等);
- \u202F: 窄空格;
- \u205F: 数学空格;
- \u3000: 全角空格。
例如使用 Python 进行正则匹配空格:
import re # 文本示例 text = "普通 空格\u3000全角空格\u00A0不间断空格\u200B零宽度空格" # 匹配所有空格 pattern = r"[\p{Zs}\u200B\uFEFF\u2000-\u200A\u202F\u205F\u3000]" matches = re.findall(pattern, text, flags=re.UNICODE) # 输出匹配结果 print(matches)
在处理文本数据时,经常会遇到不同类型的空格字符。除了最常见的半角空格(ASCII 码为 32)之外,还有全角空格(Unicode 编码为 \u3000)。这两种空格虽然在视觉上看起来相同,但在计算机内部表示却不一样,因此在进行字符串处理时需要注意区分。