提问人:Miguel Rivera 提问时间:3/19/2022 更新时间:3/21/2022 访问量:92
如何在 Ruby 中读取 ibm437 中编码的 json
How to read json encoded in ibm437 in Ruby
问:
我有一个json文件,其中包含以下数据:
{"help":true}
平台 在 Windows 2016 中,当我在记事本 ++ 中打开文本文件时,编码显示为 UCS-2 LE BOM,当我使用 ruby 显示编码时,它是 ibm437,当我尝试解析 json 时,它出现以下错误:
ruby/2.5.0/json/common.rb:156:in `parse': 765: unexpected token at ' ■{' (JSON::ParserError)
我的代码如下:
require 'json'
def current_options
dest='C:/test.json'
file = File.read(dest)
if(File.exist?(dest))
p file.encoding
p file
@data_hash ||= JSON.parse(file)
return @data_hash
else
return {}
end
end
p current_options
输出如下所示:
PS C:\> & "C:\ruby\bin\ruby.exe" .\ruby.rb #this is the file that contains my above code
#<Encoding:IBM437>
"\xFF\xFE{\x00\"\x00h\x00e\x00l\x00p\x00\"\x00:\x00t\x00r\x00u\x00e\x00}\x00"
Traceback (most recent call last):
3: from ./ruby.rb:20:in `<main>'
2: from ./ruby.rb:13:in `current_options'
1: from C:/ruby/lib/ruby/2.5.0/json/common.rb:156:in `parse'
C:/ruby/lib/ruby/2.5.0/json/common.rb:156:in `parse': 765: unexpected token at ' ■{' (JSON::ParserError)
如果我使用记事本++将编码从UCS-8 LE BOM更改为utf-2,然后在我的代码中解析它,它可以正常工作,问题是另一个应用程序管理此文件并以该编码格式创建它。
PS C:\> & "C:\ruby\bin\ruby.exe" .\ruby.rb #this is the file that contains my above code
#<Encoding:IBM437>
"{\"help\":true}"
{"help"=>true}
我尝试指定编码并强制它使用 utf-8,但仍然失败:
require 'json'
def current_options
dest='C:/test.json'
file = File.read(dest,:external_encoding => 'ibm437',:internal_encoding => 'utf-8')
if(File.exist?(dest))
p file.encoding
p file
@data_hash ||= JSON.parse(file)
return @data_hash
else
return {}
end
end
p current_options
将输出以下内容:
PS C:\> & "C:\ruby\bin\ruby.exe" .\ruby.rb #this is the file that contains my above code
#<Encoding:UTF-8>
"\u00A0\u25A0{\u0000\"\u0000h\u0000e\u0000l\u0000p\u0000\"\u0000:\u0000t\u0000r\u0000u\u0000e\u0000}\u0000"
Traceback (most recent call last):
3: from ./ruby.rb:20:in `<main>'
2: from ./ruby.rb:13:in `current_options'
1: from C:/ruby/lib/ruby/2.5.0/json/common.rb:156:in `parse'
C:/ruby/lib/ruby/2.5.0/json/common.rb:156:in `parse': 765: unexpected token at ' ■{' (JSON::ParserError)
我不确定如何解析此文件,有什么建议吗? 谢谢
答:
0赞
Schwern
3/19/2022
#1
\u00A0
是一个不间断的空格。 是一个黑色的方块。 是 null 字节。这些字符不是有效的 JSON 字符。您必须剥离或转换它们。\u25A0
\u0000
很可能是 Ruby 猜错了编码,您的文件不是真正的 IBM437,而是真正的 UCS2-LE
评论
0赞
Miguel Rivera
3/21/2022
谢谢 Schwern,你说得对,ruby 认为的编码是错误的,在 rici 的帮助下,我能够正确阅读它
0赞
rici
3/20/2022
#2
您的文件确实在带有 BOM 的 UCS2-LE 中,因此 Notepad++ 告诉您真相。
据我所知,Ruby 并没有试图弄清楚编码。执行此操作时:
file = File.read(dest)
if(File.exist?(dest))
p file.encoding
你看到的不是 Ruby 从文件内容中推断出的编码。相反,它是操作系统默认区域设置编码。在美国 OEM 安装的 Windows 上,默认编码是 IBM 437,这是原始的 DOS 编码。文件的实际编码无关紧要。
您应该能够通过提供将文件转换为 UTF-8,因为 BOM 提供字节序信息。external_encoding => 'utf-16'
评论
0赞
Miguel Rivera
3/21/2022
谢谢rici!我刚刚将其更改为 utf-16,它现在可以正确读取它:)
评论