bash - 为什么相同的字符有不同的字节表示以及如何转换
问题描述
$ printf ボ | hexdump
0000000 e3 83 9c
0000003
$ printf ボ | hexdump
0000000 e3 83 9b e3 82 99
0000006
^ 在 Mac OS 终端下输出。
从文件名中提取 6 字节(我看到有人说 mac 文件名编码问题,不太确定)
另一种是从 xml 文件内容中提取的(XML 1.0 文档文本,UTF-8 Unicode 文本)。
我试图从 xml 文件中 grep 文件名,我猜 ^ 是导致它的原因。
我试图将每个文件放在单独的文件中,希望它可以告诉我编码不同,但都显示为UTF-8 Unicode text
我的问题是这是如何发生的以及如何将 6 字节一转换为 3 字节一。
解决方案
请参阅Unicode 规范化形式。
较短的版本是由以 UTF-8 编码的单个 Unicode 代码点组成的规范组合形式。Python 示例:
>>> import unicodedata as ud
>>> bytes.fromhex('e3 83 9c').decode('utf8')
'ボ'
>>> ud.name(bytes.fromhex('e3 83 9c').decode('utf8'))
'KATAKANA LETTER BO'
较长的版本是由字母和组合标记组成的规范分解形式:
>>> import unicodedata as ud
>>> s=bytes.fromhex('e3 83 9b e3 82 99 ').decode('utf8')
>>> s
'ボ'
>>> ud.name(s[0])
'KATAKANA LETTER HO'
>>> ud.name(s[1])
'COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK'
在 Python 中,您可以通过以下方式在两种形式之间进行转换:
>>> import unicodedata as ud
>>> ud.normalize('NFD','ボ').encode('utf8').hex(sep=' ')
'e3 83 9b e3 82 99'
>>> ud.normalize('NFC','ボ').encode('utf8').hex(sep=' ')
'e3 83 9c'
推荐阅读
- excel - 将活动行从一个表剪切并粘贴到不同工作表上的另一个表
- python - 需要有关用户输入的蛇程序帮助
- amazon-web-services - 有没有办法使用 Lambda 函数在 Amazon EFS 上存储文件?
- angular - Angular2 jwt auth 通过子模块中的拦截器
- sql - 网站分析数据的存储 - 关系还是时间序列?
- mysql - .on("ready") 用mysql定义公会ID
- javascript - Vuetify fab 无法在 Firebase 上托管的 Vue.js 应用程序中正确呈现
- excel - 如何使用按钮创建循环?
- python - 访问过的烧瓶打印网址
- sql - JSON_VALUE SQL Server 函数未返回所有值