5

私はこれで非常に苦労しています:

# contained within:
"MA\u008EEIKIAI"

# should be
"MAŽEIKIAI"

# nature of string
$ p string3
"MA\u008EEIKIAI" 

$ puts string3
MAEIKIAI

$ string3.inspect
"\"MA\\u008EEIKIAI\""

$ string3.bytes
#<Enumerator: "MA\u008EEIKIAI":bytes> 

どこから始めるべきかについてのアイデアはありますか?

注: これは私の前の質問の複製ではありません

4

2 に答える 2

6

\u008Eコードポイント (16 進数)を持つ Unicode 文字が8e文字列内のその位置に現れることを意味します。この文字は、制御文字「SINGLE SHIFT TWO」です (コード表 (pdf)を参照)。文字Žは codepoint にありu017dます。ただし、 Windows CP-1252エンコーディングの位置8eにあります。どういうわけか、エンコーディングが混同されています。

これを「修正」する最も簡単な方法は、文字列 (またはデータベース レコードなど) を含むファイルを開き、正しくなるように編集することです。実際の解決策は、問題の文字列がどこから来たか、および問題のある文字列がいくつあるかによって異なります。

文字列がUTF-8 エンコーディングであると仮定すると、 は\u008Eと の 2 バイトc2で構成されます8e。2 番目のバイト は、CP-12528eの のエンコーディングと同じであることに注意してください。Ž文字列を変換する途中で、次のようになります。

string3.force_encoding('BINARY') # treat the string just as bytes for now
string3.gsub!(/\xC2/n, '')       # remove the C2 byte
string3.force_encoding('CP1252') # give the string the correct encoding
string3.encode('UTF-8')          # convert to the desired encoding

これは、このようなすべての問題を修正するための一般的な解決策ではないことに注意してください。すべての CP-1252 文字がマングルされ、UTF-8 でこのように表現された場合、このような変換に適しているわけではありません。正しいバイト (この場合のように)c2 xxが2 バイトになるものもあれば、別のバイトになるものもあります。xxc3 yyyy

于 2013-06-11T13:39:21.750 に答える
5

Regexp&String#packを使用して Unicode エスケープを変換するのはどうですか?

str = "MA\\u008EEIKIAI"
puts str    #=> MA\u008EEIKIAI

str.gsub!(/\\u(.{4})/) do |match|
  [$1.to_i(16)].pack('U')
end
puts str    #=> MA EIKIAI
于 2013-06-11T12:30:34.423 に答える