Bara för att strängen påstår sig vara UTF-8 betyder det inte att den är UTF-8. \xe9
är é
i ISO-8859-1
(AKA Latin-1) men det är ogiltigt i UTF-8; på liknande sätt, \xf1
är ñ
i ISO-8859-1 men ogiltig i UTF-8. Det tyder på att strängen faktiskt är kodad i ISO-8859-1 snarare än UTF-8. Du kan fixa det med en kombination av force_encoding
för att korrigera Rubys förvirring om den aktuella kodningen och kodning
för att koda om den som 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"
Så innan du skickar den strängen till databasen vill du:
name = name.force_encoding('iso-8859-1').encode('utf-8')
Tyvärr finns det inget sätt att på ett tillförlitligt sätt upptäcka en strängs riktiga kodning. De olika kodningarna överlappar varandra och det finns inget sätt att avgöra om è
(\xe8
i ISO-8859-1) eller č
(\xe8
i ISO-8859-2) är rätt karaktär utan manuell förnuftskontroll.