To, že řetězec tvrdí, že je UTF-8, neznamená, že je UTF-8. \xe9
je é
v ISO-8859-1
(AKA Latin-1), ale je neplatný v UTF-8; podobně, \xf1
je ñ
v ISO-8859-1, ale neplatný v UTF-8. To naznačuje, že řetězec je ve skutečnosti kódován v ISO-8859-1 spíše než v UTF-8. Můžete to opravit kombinací force_encoding
opravit Rubyin zmatek ohledně aktuálního kódování a kódovat
jej překódovat jako UTF-8:
> "Tweets en Ingl\xE9s y en Espa\xF1ol".force_encoding('iso-8859-1').encode('utf-8')
=> "Tweets en Inglés y en Español"
Takže před odesláním tohoto řetězce do databáze, kterou chcete:
name = name.force_encoding('iso-8859-1').encode('utf-8')
Bohužel neexistuje způsob, jak spolehlivě detekovat skutečné kódování řetězce. Různá kódování se překrývají a neexistuje způsob, jak zjistit, zda è
(\xe8
v ISO-8859-1) nebo č
(\xe8
v ISO-8859-2) je správný znak bez ruční kontroly zdravého rozumu.