4

我正在开发一个应用程序,其中 ruby​​ sidekiq 进程调用第 3 方并将数据解析到数据库中。

我正在使用我的 orm 的续集广告。

我在结果中得到了一些奇怪的字符,例如:

"Tweets en Ingl\xE9s y en Espa\xF1ol"

当试图将其保存到 postgres 时,会发生以下错误:

Sequel::DatabaseError: PG::CharacterNotInRepertoire: ERROR: invalid byte sequence for encoding "UTF8": 0xe9 0x73 0x20

奇怪的是字符串认为它是 UTF-8,如果我检查编码名称,它会说:

name.encoding.name #UTF-8

我可以做些什么来确保数据的格式对 postgres 正确?

4

1 回答 1

8

仅仅因为字符串声称是 UTF-8 并不意味着它是 UTF-8。\xe9ISO-8859-1é (AKA Latin-1)中,但在 UTF-8 中无效;同样,在ISO-8859-1 中,但在 UTF-8 中无效。这表明该字符串实际上是用 ISO-8859-1 而不是 UTF-8 编码的。您可以通过以下组合来修复它,以纠正 Ruby 对当前编码的混淆并将其重新编码为 UTF-8:\xf1ñforce_encodingencode

> "Tweets en Ingl\xE9s y en Espa\xF1ol".force_encoding('iso-8859-1').encode('utf-8')
=> "Tweets en Inglés y en Español" 

因此,在将该字符串发送到您想要的数据库之前:

name = name.force_encoding('iso-8859-1').encode('utf-8')

不幸的是,没有办法可靠地检测字符串的真实编码。各种编码重叠,如果没有手动健全性检查,就无法判断è\xe8在 ISO-8859-1 中)或č(在 ISO-8859-2 中)是否是正确的字符。\xe8

于 2013-10-31T18:03:16.447 回答