Je reçois un Encoding::UndefinedConversionError - "\xC2" from ASCII-8BIT to UTF-8
Chaque fois que j'essaie de convertir un hachage en une chaîne JSON. J'ai essayé avec [.encode | .force_encoding](["UTF-8" | "ASCII-8BIT" ])
, enchaînant .encode
Avec .force_encoding
, En arrière, en changeant les paramètres mais rien ne semblait fonctionner alors j'ai attrapé l'erreur comme ceci:
begin
menu.to_json
rescue Encoding::UndefinedConversionError
puts $!.error_char.dump
p $!.error_char.encoding
end
Où menu est le dataset.to_hash d'une suite avec le contenu d'une base de données MySQL, l'encodage utf8_general_ci et a renvoyé ceci:
"\ xC2"
<#Encoding: ASCII-8BIT>
L'encodage ne change jamais, peu importe ce que .encode
/.force_encoding
J'utilise. J'ai même essayé de remplacer la chaîne .gsub!(/\\\xC2/)
sans chance.
Des idées?
menu.to_s.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?')
Cela a fonctionné parfaitement, j'ai dû remplacer quelques caractères supplémentaires mais il n'y a plus d'erreurs.
Qu'attendez-vous pour "\ xC2"? Probablement un Â
Avec ASCII-8BIT, vous avez des données binaires et Ruby ne peux pas décider ce qui devrait être.
Vous devez d'abord définir l'encodage avec force_encoding
.
Vous pouvez essayer le code suivant:
Encoding.list.each{|enc|
begin
print "%-10s\t" % [enc]
print "\t\xC2".force_encoding(enc)
print "\t\xC2".force_encoding(enc).encode('utf-8')
rescue => err
print "\t#{err}"
end
print "\n"
}
Le résultat est les valeurs possibles dans différents encodages pour votre "\ xC2".
Le résultat peut dépendre de votre format de sortie, mais je pense que vous pouvez faire une bonne supposition, quel encodage vous avez.
Lorsque vous avez défini l'encodage dont vous avez besoin (probablement cp1251), vous pouvez
menu.force_encoding('cp1252').to_json
Voir aussi le commentaire de Kashyaps.
Si vous ne vous souciez pas de perdre les personnages étranges, vous pouvez les emporter:
str.force_encoding("ASCII-8BIT").encode('UTF-8', undef: :replace, replace: '')
Votre solution acceptée automatiquement ne fonctionne pas, il n'y a effectivement aucune erreur, mais ce n'est PAS JSON.
J'ai résolu le problème en utilisant la gem oj, cela fonctionne maintenant trouver. Elle est également plus rapide que la bibliothèque JSON standard.
Écriture:
menu_json = Oj.dump menu
En train de lire :
menu2 = Oj.load menu_json
https://github.com/ohler55/oj pour plus de détails. J'espère que cela aidera.