【问题标题】:Correctly use UTF-8 chars as hash keys正确使用 UTF-8 字符作为哈希键
【发布时间】:2016-04-03 02:54:52
【问题描述】:

以下代码从 UTF-8 文件中读取内容,计算每个字符串中的字母(使用哈希)并将结果输出到另一个文件。

问题是哈希中的每个字母都表示为 utf-8 代码,而不是符号。

如何正确使用符号,而不是哈希中的 utf-8 代码?

#encoding=utf-8
#Encoding.filesystem = "UTF-8"
length = 0

letters = Hash.new(0)

File.open("hist_1.txt", "r:UTF-8") do |f|
  f.each_line do |line|
    line.chomp
    line.chars.each do |l|
      l = l.encode("Windows-1251", "UTF-8")
      letters[l] += 1 
    end
    end
  end
end

a = letters.sort
#
#p a
puts a
File.open("results.txt", "w:UTF-8") { |file| file.write a }

【问题讨论】:

  • 您能分享一个输入文件的例子吗?
  • dropbox.com/s/azjhhmbwy7vzjld/hist_1.txt?dl=0 无法将文件附加到帖子(
  • 复制粘贴到 Dropbox 显然会使文件 utf 编码,因此没有意义。无论如何,不​​管你是否关心输入是cp1251,你为什么打开它为utf-8
  • 文件内容为 utf-8。我想阅读 utf-8 内容/
  • 我不明白你的意思是“问题是哈希中的每个字母都表示为utf-8代码,而不是符号”,你能分享一个例子吗?不知道是不是你的终端没有正确显示utf8?

标签: ruby hash utf-8


【解决方案1】:

我相信虽然你想要的输出是关于字母的,但你不应该使用chars,也不应该使用codepoints

content = File.read("hist_1.txt", encoding: "UTF-8") # read the whole file
#       ⇓⇓⇓⇓⇓⇓⇓⇓⇓ split to letters
content.split(//).inject(Hash.new(0)) do |memo, cp|
  memo[cp] += 1
  memo
end
#⇒ {"В"=>1, "о"=>5, "т"=>5, " "=>9, "п"=>4, "э"=>1, ...}

现在您可能想在哈希键上调用 downcase 并去掉空格和标点符号。

【讨论】:

  • File.read("hist_1.txt", "r:UTF-8") - 不行,你必须使用 File.read("hist_1.txt", encoding: "UTF -8")。最后的代码比我的更优雅,但有同样的问题。
  • 抱歉File#read 的语法错误,我已修复。其余的:如果您确定文件是 UTF-8 格式,则上面的代码可以工作。反之亦然,它不起作用,这意味着您在cp1251 中有一个文件,请尝试以这种方式阅读它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 1970-01-01
  • 2012-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多