0

我有一个 MySQL 设置UTF-8,除了来自 SqlAlchemy 的连接之外,所有表/字段和字符集设置都是。

我最近将连接字符集更改为在任何地方UTF-8使用UTF-8

更改此设置时,数据库中的旧值会呈现错误,例如:

Björn => Björn

这没问题,我只是收集值并对其进行编码,使用python中的encode方法,然后将它们重新放入。

当我尝试转换设置更改后插入的值时会出现问题,这些值已经正确。

有没有一种好方法来确定我是否应该对值进行编码?

4

1 回答 1

0

您的旧编码大概是拉丁语 1?

您可能可以通过查看连续字节来检测字符串何时使用 Latin-1 而不是 UTF-8 编码。UTF-8 标准有一个独特的代码页布局,我们可以用它来检测一段文本是用 Latin-1 还是 UTF-8 编码的:

  • 00-7F 范围内的任何字节都是安全的,当然,这些是 ASCII 值,并且这些代码点在两种编码之间匹配。这里没有帮助,不需要帮助。

  • 字节 C0、C1 和 F5-FF在 UTF-8 编码中是非法的。任何包含这些的字符串都必须是 Latin-1 编码的。

  • C2-DF 范围内的字节必须后跟 80-BF 范围内的字节。如果您有任何两个与此不匹配的字节,您可能手上有一个 Latin-1 编码的字符串。

如果您曾经编码的只是 Latin-1 字符(直到 Unicode 代码点 255),您可以在这里停下来;包含 E0-FF 范围内的字节的任何内容都是旧的 Latin-1 数据。

如果您在切换后确实以 UTF-8 添加了数据,这超出了 Latin-1 范围,您还需要包含以下规则:

  • E0-EF 范围内的字节标记一个 3 字节的 UTF-8 字符。接下来的两个字节必须再次落在 80-BF 范围内。

3 UTF-8 字节数据涵盖了BMP的其余部分,您不太可能在此之外进行编码。如果您在此之外进行编码,请查找:

  • F0-F4 范围内的字节必须紧跟 80-BF 范围内的 3 个字节。

如果所有这些条件都匹配,您可能有一个 UTF-8 字符串,但您不能 100% 确定。如果其中任何一个匹配,您肯定有一个 Latin-1 字符串。但是,Latin-1 代码点 C2-DF 不太可能跟随代码点 80-BF,因为后者的大部分要么是控制代码,要么是更深奥的变音符号。也许您可以通过寻找多个 2 字节 UTF-8 序列来进一步缩小范围,以提高您的置信度分数。

所以,总而言之 (tl;dr):您可以通过查看多字节序列来找到大多数Latin-1 编码的字符串。如果它们不属于严格的 UTF-8 标准,那么您手头上有一个 Latin-1 字符串。

于 2012-08-14T09:59:27.873 回答