Unicode编码十六进制范围比较出现异常结果的问题排查
如何在Python中区分日文中的汉字与平假名/片假名
你遇到的问题核心在于错误地用UTF-8字节串的大小来替代Unicode码点的数值比较——虽然UTF-8是Unicode的编码实现,但字节串的排序逻辑和Unicode码点的数值排序并非等价,这种做法容易出现不可预期的问题。
Unicode与UTF-8的转换逻辑
每个字符对应唯一的Unicode码点(比如“青”的码点是十六进制0x9752),UTF-8是将该码点转换为字节序列的编码方式。以“青”为例:
- 码点
0x9752属于0x0800-0xFFFF区间,对应3字节UTF-8格式:1110xxxx 10xxxxxx 10xxxxxx - 将
0x9752拆分为二进制:1001 0111 0101 0010 - 填充到UTF-8格式的空位中,得到字节序列:
0xE9 0x9D 0x92,也就是你看到的b'\xe9\x9d\x92'
正确的实现方式
直接通过ord()函数获取字符的Unicode码点,与CJK统一汉字的区间(0x4E00-0x9FAF)对比即可,这种方式更可靠且简洁:
def find_kanji(chars): # CJK统一汉字的Unicode码点区间:十六进制0x4E00到0x9FAF min_kanji_code = 0x4E00 max_kanji_code = 0x9FAF found_kanji = [] for char in chars: char_code = ord(char) if min_kanji_code <= char_code <= max_kanji_code: found_kanji.append(char) return found_kanji # 测试示例 print(find_kanji('吸い込む')) # 输出:['吸', '込']
为什么原代码失效?
原代码中用UTF-8字节串做区间对比的方式不可靠:虽然同一长度的UTF-8字节序列排序和码点排序一致,但如果字符的UTF-8长度不同(比如存在4字节的CJK扩展汉字),或者字符输入有误(比如你用的“䶿”如果不是正确的0x9FAF码点字符),都会导致对比逻辑失效。直接使用码点对比则完全避免了这些问题。
内容的提问来源于stack exchange,提问作者J.Doe
相关产品推荐
相关产品推荐

