修复Ruby中编码错误的字符串 背景

修复Ruby中编码错误的字符串 背景,ruby,character-encoding,Ruby,Character Encoding,我有一个Postgres数据库中的数据,它在某些时候被错误地编码了 数据库是UTF-8编码的。该表有一列包含YAML序列化数据。某些行包含非ascii字符,这些字符似乎由其两字节UTF等价物表示。更容易显示: > puts data # --- # :method_name: new # :method_args: # - "M\xC3\xB6bler" # - "" # - false # - "" # - test # - f8685480-a36b-012f-54c

我有一个Postgres数据库中的数据,它在某些时候被错误地编码了

数据库是UTF-8编码的。该表有一列包含YAML序列化数据。某些行包含非ascii字符,这些字符似乎由其两字节UTF等价物表示。更容易显示:

> puts data
#  ---
#  :method_name: new
#  :method_args:
#  - "M\xC3\xB6bler"
#  - ""
#  - false
#  - ""
#  - test
#  - f8685480-a36b-012f-54c1-1093e95ec0bb

> data.encoding
# => # <Encoding:UTF-8>
但是,在这种情况下,保留原始字节,以便我们可以转换回UTF:

> string.force_encoding("utf-8")
# => "ö"
打印
\xC3\xB6
似乎只是显示在ASCII-8BIT中毫无意义的字节的一种方式。您可以通过调用
.chars
来说明这一点:

> string.chars
# => ["\xC3", "\xB6"]
但是在来自数据库的字符串中,
\xC3\xB6
实际上是八个字符

> data[42..49].chars
# => ["\\", "x", "C", "3", "\\", "x", "B", "6"]
正因为如此,您不能只强制使用ASCII-8bit,然后再返回—这是我第一次尝试解决方案

我的下一个想法是以某种方式恢复原始字节,但结果比我想象的要困难

这里提出了一种可能的(黑客式)解决方案:

这个解决方案对我不起作用,可能是因为字符串代表YAML

问题: 如何恢复原始unicode字符

我想我可以写一个巨大的gsub表达式,但我宁愿避免

我想我可以写一个巨大的gsub表达式,但我宁愿避免

不是真的那么可怕:)

string=“M\\xC3\\xB6bler”
字符串编码
# => #
将string.gsub(/\\x([0-9a-zA-Z]{2})/){$1.to_i(16.chr}
#=>Möbler
> data[42..49].chars
# => ["\\", "x", "C", "3", "\\", "x", "B", "6"]
string = "M\\xC3\\xB6bler"
string.encoding
# => #<Encoding:UTF-8>

puts string.gsub(/\\x([0-9a-zA-Z]{2})/) { $1.to_i(16).chr }
# => Möbler