提问人:rellampec 提问时间:5/10/2022 最后编辑:rellampec 更新时间:5/10/2022 访问量:172
ruby:为什么 utf-8 中的 File.read 无法读取有效的 utf-8 字符?
ruby: How comes File.read in utf-8 fails to read a valid utf-8 character?
问:
上下文
- 尝试使用编码的文件进行解析
ruby 2.6.3+
csv
utf-8
- 该文件包含一个引发
CSV::MalformedCSVError
的字符 - 隔离后,感兴趣的字符似乎是单个 LOW-9 引号 ()。这个。
U+201A
‚
- 该字符似乎由 (3 个字节,十六进制:或) (ref1, ref2
UTF-8
e2809a
\xe2\x80\x9a
)
test.csv
文件内容
"value"
"abc‚d"
使用类解析时出错:CSV
irb(main):001:0> require 'csv'
=> true
irb(main):002:0> CSV.read("test.csv", **{headers: true, skip_blanks: true, encoding: "utf-8"})
Traceback (most recent call last):
2: from C:/ruby/Ruby26-x64/lib/ruby/2.6.0/csv/parser.rb:297:in `parse'
1: from C:/ruby/Ruby26-x64/lib/ruby/2.6.0/csv/parser.rb:711:in `build_scanner'
CSV::MalformedCSVError (Invalid byte sequence in UTF-8 in line 2.)
虽然是受支持的字符:\u201a
utf-8
irb(main):001:0> str = "\u201a"
=> "‚"
irb(main):002:0> str.ord.to_s(16)
=> "201a"
irb(main):003:0> str.encoding.name
=> "UTF-8"
irb(main):004:0> str.unpack("H*")
=> ["e2809a"]
处理编码错误scrub
将 String#scrub
与 a 一起使用似乎没有得到 SINGLE LOW-9 QUOTATION MARK。请参阅下面的代码(参考原始代码):block
x82
‚
irb(main):001:0> content = File.read('test.csv', encoding: 'utf-8')
=> "\"value\"\n\"abc\x82d\"\n"
irb(main):002:0> content.scrub! do |bytes|
irb(main):003:1* "<" + bytes.unpack('H*')[0] + ">"
irb(main):004:1> end
=> "\"value\"\n\"abc<82>d\"\n"
irb(main):005:0> require 'csv'
=> true
irb(main):006:0> CSV.parse(content, **{headers: true, skip_blanks: true, encoding: "utf-8"}).each do |row|
irb(main):007:1* pp row["value"]
irb(main):008:1> end
"abc<82>d"
=> #<CSV::Table mode:col_or_row row_count:2>
如上所示,SINGLE LOW-9 引号替换为 ,这是违规字节的十六进制表示形式。在这一点上,我有点迷茫。<82>
问题
虽然似乎一致地有一个 和 无法找到 UTF-8 字符的 3 个字节(而是获取一个字节:):CSV::MalformatedCSVError
String#scrub
e2809a
0x82
- 如果字符受 (as ) 支持,则错误的根本原因是什么?
\u201a
UTF-8
e2809a
- 在文本编辑器 (Notepad++) 中打开文件,字符将正确显示在文本区域上。当我在此 Unicode 查找中复制并粘贴字符 () 时,它会正确识别该字符。所以它似乎没有什么问题。
csv
‚
- 在文本编辑器 (Notepad++) 中打开文件,字符将正确显示在文本区域上。当我在此 Unicode 查找中复制并粘贴字符 () 时,它会正确识别该字符。所以它似乎没有什么问题。
- 查看上面的代码示例 (),和 的用法似乎没有问题。您能否确认(解释)或丢弃错误是否与这些方法的使用有关?
irb
CSV.read
File.read
也许没有什么可以修复的,不是意料之中的,但我不确定。如果不是不可能的话,创建一个通用的解决方案来正确发现违规字符似乎相当困难。ruby
答: 暂无答案
评论
UTF-8
Notepad++