我需要在拉丁语 1 --> UTF-8 中修复隐藏的编码错误吗?
Posted
技术标签:
【中文标题】我需要在拉丁语 1 --> UTF-8 中修复隐藏的编码错误吗?【英文标题】:Are there hidden encoding errors that I need to fix in Latin 1 --> UTF-8? 【发布时间】:2015-01-23 22:10:48 【问题描述】:我是否仍需要对看起来完全正常的文本运行完整的 latin1 到 UTF 8 转换?
我正在换论坛软件,旧论坛数据库使用的是 Latin1 编码。新的论坛数据库对表使用 UTF8 编码。
看起来导入器脚本直接从一个表复制到另一个表,而没有尝试修复任何编码问题。
我一直在使用基于此处列出的转换信息的查找和替换来手动修复可见错误:http://www.i18nqa.com/debug/utf8-debug.html
文本的其余部分看起来很好并且完全可读。
我的有限理解是 UTF-8 向后兼容 ASCII,而 Latin1 主要是 ASCII,所以只有边缘情况不同,需要更新。
那么我还需要对看起来完全正常的文本运行完整的 latin1 到 UTF 8 转换吗?
我宁愿不这样做,因为在以 UTF 8 存储后,我已经更改了一些字段上的一些 BB 代码标签,因此担心这些更新会将 UTF8 字符卡在 Latin1 字符的中间, 并且尝试对混合字符集进行完全转换只会使事情变得更糟。
【问题讨论】:
嗯,你基本上是在问这里是否可以偷工减料。严格的方法是从 Latin1 解码并编码为 UTF-8,然后才对内容进行更改。低于此值的任何内容都存在数据不正确的风险。 我不确定,因为我认为 UTF-8 向后兼容 ASCII,而 Latin1 主要是 ASCII,所以只有边缘情况不同,需要更新。 最好不要假设它们具有的编码和属性(将它们视为黑匣子)。要将 A 转换为 B,您需要从 A 解码并编码为 B。 How to detect UTF-8 characters in a Latin1 encoded column - mysql的可能重复 嗯,答案可能相似,但问题不同。我什至在问这个问题之前就专门阅读了这个问题。一个是关于如何检测差异的,这个是关于是否可以走捷径......从功能上我需要知道的是“只要你转换这个范围内的所有字符,就可以走捷径。”跨度> 【参考方案1】:在 0x80..0xFF 范围内来自 ISO 8859-1(拉丁文 1)的任何字符都需要在 UTF-8 中重新编码为 2 个字节。第一个字节是 0xC2 为 0x80..0xBF; 0xC0..0xFF 的第一个字节是 0xC3。第二个字节是通过将两个最高有效位设置为 1 和 0 从拉丁语 1 的原始值派生的。对于字符 0x80..0xBF,第二个字节的值与拉丁语 1 相同。如果您使用的是 8859- 15,你可能有一些更复杂的转换(欧元符号与其他拉丁 1 字符的编码不同)。
有很多工具可以提供帮助。 iconv
就是其中之一。
【讨论】:
那么如果不在那个范围内,就不需要转换了?我可以使用此查询找到这些字符吗?SELECT post_id, CONVERT(CONVERT(message USING BINARY) USING latin1) AS latin1, CONVERT(CONVERT(message USING BINARY) USING utf8) AS utf8 FROM xf_post WHERE CONVERT(message USING BINARY) RLIKE CONCAT('[', UNHEX('80'), '-', UNHEX('FF'), ']')
Unicode 代码点 U+0000 到 U+007F 与 ISO 8859-x 代码点 0x00 到 0x7F 相同,并且在 UTF-8 中编码为 0x00..0x7F 范围内的单个字节,因此无需担心“纯 ASCII”范围内的字符。您的查询是否有效的简短回答是“我不知道”。我能说的最好的就是“也许”和“试试看”。将一些重音字符放入 8859-1 中的表中,然后尝试查询。如果有效,答案是肯定的。如果没有,没有。
谢谢!顺便说一句,从这里提取的查询似乎适用于基本测试:***.com/questions/9304485/…
看起来这可能是这个问题的合适副本;它似乎正在解决同样的问题(在 MySQL 中从 Latin 1 迁移到 UTF-8)。以上是关于我需要在拉丁语 1 --> UTF-8 中修复隐藏的编码错误吗?的主要内容,如果未能解决你的问题,请参考以下文章