2010-07-01 12 views
10

Ich habe derzeit Probleme mit den Ergebnissen der Amazon API.Wie konvertiert man die Zeichencodierung mit Rubin 1.9

der Dienst gibt einen String mit Unicode-Zeichen: Lernen Objective \ xE2 \ x80 \ x93C auf dem Mac (Learn Series)

mit Ruby 1.9.1 die Zeichenfolge konnte nicht einmal verarbeitet worden:

REXML::ParseException: #<Encoding::CompatibilityError: incompatible encoding regexp match (UTF-8 regexp with ASCII-8BIT string)> 

... 

Exception parsing 

Line: 1 

Position: 1636 

Last 80 unconsumed characters: 

Learn Objective–C on the Mac (Learn Series) 
+2

I Ich empfehle das Lesen * Das absolute Minimum Jeder Softwareentwickler Absolut, Positiv muss über Unicode und Zeichensätze (keine Entschuldigungen!) * wissen (http://www.joelonsoftware.com/articles/Unicode.html), selbst wenn Sie bereits sind Fa Miliar mit Codierungen und so. – ewall

+2

Ich las vor kurzem Yehuda Katz Artikel über Kodierung in 1.9 und dachte: WTF ?! (http://yehudakatz.com/2010/05/17/encodings-unabridged/) der Artikel, den Sie verknüpften, ist ausgezeichnet. – phoet

Antwort

29

Wie die Ausnahme angibt, ist Ihre Zeichenfolge ASCII-8BIT-codiert. Sie sollten die Codierung ändern. Es gibt eine long story darüber, aber wenn Sie Interesse an schnellen Lösung sind, nur force_encoding auf der Saite, bevor Sie tun, um jede Verarbeitung:

s = "Learn Objective\xE2\x80\x93C on the Mac" 
# => "Learn Objective\xE2\x80\x93C on the Mac" 
s.encoding 
# => #<Encoding:ASCII-8BIT> 
s.force_encoding 'utf-8' 
# => "Learn Objective–C on the Mac" 
+0

ist dies ein Problem der Antwort, die vom Amazon-Service gesendet wird? Soll es einen anderen Inhaltstyp festgelegt haben? – phoet

+0

Ich habe nicht mit AWS gearbeitet, daher weiß ich nicht, wie diese Zeichenfolge geladen wurde, aber Sie können die Standardcodierung auf (Ruby) Anwendungsebene setzen, also ist es wahrscheinlich, dass es das Problem lösen würde - mehr über den Link in die Antwort. BTW, ich glaube nicht, dass es ein _issue_ überhaupt gibt, Ruby einfach nicht (und sollte nicht) versuchen zu erraten, welche Codierung die Zeichenfolge, die es empfängt, ist in. –

+0

Wahrscheinlich; das würde bedeuten, dass HTTParty sich darum kümmern sollte. –

25

Mladen Lösung funktioniert, wenn alles, was tatsächlich in ASCII-8BIT codiert wird, umgewandelt werden direkt zu UTF-8. Es bricht ab, wenn Zeichen vorhanden sind, die 1) ungültig oder 2) undefiniert in UTF-8 sind. Allerdings wird diese Arbeit (in 1.9.2 oder höher.

new_str = s.encode('utf-8', 'binary', :invalid => :replace, 
    :undef => :replace, :replace => '') 

ASCII-8BIT ist effektiv binär Dieser Code konvertiert die Kodierung UTF-8, während ordnungsgemäß mit ungültigen und nicht definierte Zeichen Umgang Der. Ungültige Option gibt an, dass ungültige Zeichen ersetzt werden sollen Die Option: undef legt fest, dass undefinierte Zeichen ersetzt werden sollen und die Option: replace legt fest, durch welche ungültigen oder undefinierten Zeichen ersetzt werden soll In diesem Fall habe ich mich dafür entschieden, sie einfach zu entfernen

+0

uh, sieht gut aus! werde das versuchen! – phoet

+0

hast du den 'Fallback' Mechanismus versucht? Ich habe versucht, einige 'Windows-1252'-Kodierungen wie' u00E4' für ä zu ersetzen, aber es hat nicht funktioniert :( – phoet

+0

Das hat mir den Tag gerettet, als ich eine Datei in einen HTTP-Body zum Posten streamte ... Vielen Dank! +1 – stuartc