Ce n'est pas parce que la chaîne prétend être UTF-8 qu'elle est UTF-8. \xe9
est é
dans ISO-8859-1
(AKA Latin-1) mais il n'est pas valide en UTF-8 ; de même, \xf1
est ñ
dans ISO-8859-1 mais invalide dans UTF-8. Cela suggère que la chaîne est en fait codée en ISO-8859-1 plutôt qu'en UTF-8. Vous pouvez le réparer avec une combinaison de force_encoding
pour corriger la confusion de Ruby sur l'encodage actuel et encode
pour le ré-encoder en 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"
Ainsi, avant d'envoyer cette chaîne à la base de données, vous souhaitez :
name = name.force_encoding('iso-8859-1').encode('utf-8')
Malheureusement, il n'existe aucun moyen de détecter de manière fiable le véritable encodage d'une chaîne. Les différents encodages se chevauchent et il n'y a aucun moyen de savoir si č
(\xe8
dans ISO-8859-1) ou č
(\xe8
dans ISO-8859-2) est le bon caractère sans vérification manuelle de cohérence.