2011-08-27 55 views
0

我运行的Ruby 1.9.2并试图修复一些破碎的UTF-8文本输入在文本字面上"\\354\\203\\201\\355\\221\\234\\353\\252\\205"并把它变成它的正确韩国"상표명"转换整数UTF-8(韩国)

然而在搜索了一段时间并尝试了几个方法之后,我仍然发现了一些乱码。 它作为转义字符例如混乱的3个线工程精细

# encoding: utf-8 
puts "상표명" # Target string 
# Output: "상표명" 

puts "\354\203\201\355\221\234\353\252\205" # Works with escaped characters like this 
# Output: "상표명" 

# Real input is a string 
input = "\\354\\203\\201\\355\\221\\234\\353\\252\\205" 

# After some manipulation got it into an array of numbers 
puts [354, 203,201,355,221,234,353,252,205].pack('U*').force_encoding('UTF-8') 
# Output: ŢËÉţÝêšüÍ (gibberish) 

我敢肯定,这一定是某个地方回答,但我没有设法找到它。

回答

10

这是你想要做的就是你UTF-8朝鲜语文本的内容:

s = "\\354\\203\\201\\355\\221\\234\\353\\252\\205" 
k = s.scan(/\d+/).map { |n| n.to_i(8) }.pack("C*").force_encoding('utf-8') 
# "상표명" 

,这是它如何工作的:

  1. 输入字符串是好的,定期所以我们可以用scan取出个人号码。
  2. 然后mapto_i(8)八进制值(如Henning Makholm所述)转换为整数。
  3. 现在我们需要将我们的整数列表转换为字节,所以我们pack('C*')得到一个字节字符串。该字符串将具有BINARY编码(AKA ASCII-8BIT)。
  4. 我们碰巧知道这些字节确实代表UTF-8,所以我们可以用force_encoding('utf-8')强制该问题。

你缺少的主要是你的pack格式; 'U'的意思是“UTF-8字符”,并期望一个Unicode代码点的数组,每个都由一个整数表示,'C'需要一个字节数组,这就是我们所拥有的。

+0

谢谢!我想我现在明白了。 –

2

\354等等都是八进制转义,不是小数,所以你不能只是写他们为354,以获得字节的整数值。

+0

+1,完全有效的答案。我只是想知道主要是C#程序员,'force_encoding'真的会做他认为应该做的事吗?看起来很奇怪,让你像这样在飞行中改变编码。 – Blindy

+0

@Bindind:是的,显然[这是Ruby如何处理ecodings](http://blog.grayproductions.net/articles/ruby_19s_string)。 –

+0

@Bindind:分类。它只会在字节确实代表UTF-8文本时起作用,如果你使用['Iconv'](http://ruby-doc.org/stdlib/libdoc/iconv/rdoc/classes/Iconv.html)if您希望在保留字符的同时转码字符串。 –