xfe - ruby utf 8




Ruby Konvertierung von String-Codierung von ISO-8859-1 zu UTF-8 funktioniert nicht (2)

Es gibt einen Unterschied zwischen force_encoding und encode . Erstere legt die Codierung für die Zeichenfolge fest, während letztere die Inhalte der Zeichenfolge tatsächlich in die neue Codierung umsetzt. Folglich verursacht der folgende Code Ihr Problem:

string = "Norrlandsvägen"
string.force_encoding('iso-8859-1')
puts string.encode('utf-8') # Norrlandsvägen

Während der folgende Code Ihre Inhalte korrekt codiert:

string = "Norrlandsvägen".encode('iso-8859-1')
string.encode!('utf-8')

Hier ist ein Beispiel, das in irb läuft:

irb(main):023:0> string = "Norrlandsvägen".encode('iso-8859-1')
=> "Norrlandsv\xE4gen"
irb(main):024:0> string.encoding
=> #<Encoding:ISO-8859-1>
irb(main):025:0> string.encode!('utf-8')
=> "Norrlandsvägen"
irb(main):026:0> string.encoding
=> #<Encoding:UTF-8>

Ich versuche, eine Zeichenfolge von ISO-8859-1-Codierung in UTF-8 zu konvertieren, aber ich kann nicht scheinen, dass es funktioniert. Hier ist ein Beispiel von dem, was ich in irb getan habe.

irb(main):050:0> string = 'Norrlandsvägen'
=> "Norrlandsvägen"
irb(main):051:0> string.force_encoding('iso-8859-1')
=> "Norrlandsv\xC3\xA4gen"
irb(main):052:0> string = string.encode('utf-8')
=> "Norrlandsvägen" 

Ich bin mir nicht sicher, warum Norrlandsvägen in iso-8859-1 in utf-8 in Norrlandsvägen umgewandelt wird.

Ich habe versucht, codieren, codieren !, encodieren (destinationEncoding, originalEncoding), iconv, force_encoding und alle Arten von seltsamen Work-arounds, die ich denken konnte, aber nichts scheint zu funktionieren. Kann mir bitte jemand helfen / in die richtige Richtung weisen?

Ruby-Neuling zieht immer noch Haare wie verrückt, aber dankbar für alle Antworten hier ... :)

Hintergrund dieser Frage: Ich schreibe ein Juwel, das eine XML-Datei von einigen Websites (die ISO-8859-1-Codierung haben wird) herunterladen und in einem Speicher speichern, und ich möchte es zuerst in UTF-8 konvertieren. Aber Wörter wie Norrlandsvägen bringen mich immer wieder durcheinander. Wirklich jede Hilfe würde sehr geschätzt werden!

[UPDATE]: Ich habe festgestellt, dass das Ausführen von Tests in der IRB-Konsole mir verschiedene Verhaltensweisen gibt. Hier ist also, was ich in meinem eigentlichen Code habe:

def convert_encoding(string, originalEncoding) 
  puts "#{string.encoding}" # ASCII-8BIT
  string.encode(originalEncoding)
  puts "#{string.encoding}" # still ASCII-8BIT
  string.encode!('utf-8')
end

aber die letzte Zeile gibt mir den folgenden Fehler:

Encoding::UndefinedConversionError - "\xC3" from ASCII-8BIT to UTF-8

Dank @ Amadans Antwort unten habe ich festgestellt, dass \xC3 tatsächlich in irb auftaucht, wenn du \xC3 :

irb(main):001:0> string = 'ä'
=> "ä"
irb(main):002:0> string.force_encoding('iso-8859-1')
=> "\xC3\xA4"

Ich habe auch versucht, dem Ergebnis von string.encode(originalEncoding) eine neue Variable zuzuweisen, bekam aber einen noch seltsameren Fehler:

newString = string.encode(originalEncoding)
puts "#{newString.encoding}" # can't even get to this line...
newString.encode!('utf-8')

und der Fehler ist Encoding::UndefinedConversionError - "\xC3" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to ISO-8859-1

Ich bin immer noch ziemlich verloren in all dem Coding Chaos, aber ich bin wirklich dankbar für alle Antworten und Hilfe, die jeder mir gegeben hat! Danke vielmals! :)


Sie weisen eine Zeichenfolge in UTF-8 zu. Es enthält ä . UTF-8 repräsentiert ä mit zwei Bytes.

string = 'ä'
string.encoding
# => #<Encoding:UTF-8>
string.length
# 1
string.bytes
# [195, 164]

Dann erzwingen Sie, dass die Bytes so interpretiert werden, als wären sie ISO-8859-1, ohne die zugrunde liegende Repräsentation tatsächlich zu ändern. Dies beinhaltet nicht mehr. Es enthält zwei Zeichen, Ã und ¤ .

string.force_encoding('iso-8859-1')
# => "\xC3\xA4"
string.length
# 2
string.bytes
# [195, 164]

Dann übersetze du das in UTF-8 . Da es sich nicht um eine Neuinterpretation handelt, sondern um eine Übersetzung, behalten Sie die zwei Zeichen, die jetzt in UTF-8 codiert sind:

string = string.encode('utf-8')
# => "ä" 
string.length
# 2
string.bytes
# [195, 131, 194, 164]

Was Sie vermissen ist die Tatsache, dass Sie ursprünglich keinen ISO-8859-1-String haben, wie Sie es von Ihrem Web-Service gewohnt sind - Sie haben Kauderwelsch. Zum Glück ist dies alles in Ihren Konsolentests; Wenn Sie die Antwort der Website mit der richtigen Eingabecodierung lesen, sollte alles in Ordnung funktionieren.

Lassen Sie uns für Ihren Konsolentest demonstrieren, dass alles, wenn Sie mit einer geeigneten ISO-8859-1-Zeichenfolge beginnen, funktioniert:

string = 'Norrlandsvägen'.encode('iso-8859-1')
# => "Norrlandsv\xE4gen"
string = string.encode('utf-8')
# => "Norrlandsvägen"

EDIT Für Ihr spezifisches Problem sollte dies funktionieren:

require 'net/https'
uri = URI.parse("https://rusta.easycruit.com/intranet/careerbuilder_se/export/xml/full")
options = {
  :use_ssl => uri.scheme == 'https', 
  :verify_mode => OpenSSL::SSL::VERIFY_NONE
}
response = Net::HTTP.start(uri.host, uri.port, options) do |https|
  https.request(Net::HTTP::Get.new(uri.path))
end
body = response.body.force_encoding('ISO-8859-1').encode('UTF-8')




iconv