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表示带有代码点(十六进制)的 unicode 字符8e出现在字符串中的该点。这个字符是控制字符“SINGLE SHIFT TWO”(见代码表(pdf))。字符Ž位于 codepoint u017d。但是它在8eWindows CP-1252编码中的位置。不知何故,您的编码混淆了。

“修复”此问题的最简单方法可能只是打开包含字符串(或数据库记录或其他任何内容)的文件并将其编辑为正确。真正的解决方案将取决于有问题的字符串来自哪里以及您有多少坏字符串。

假设字符串采用UTF-8 编码\u008E将由两个字节c28e. 请注意,第二个字节 ,与CP-1252 中8e的编码相同。Ž转换字符串的方式是这样的:

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,其中xx正确的字节(如本例中),其他将c3 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 回答