有没有办法从UTF-8编码的文件中删除BOM?

Abe*_*Abe 29 ruby byte-order-mark

有没有办法从UTF-8编码的文件中删除BOM?

我知道我的所有JSON文件都是用UTF-8编码的,但编辑JSON文件的数据输入人员用BOM将其保存为UTF-8.

当我运行我的Ruby脚本来解析JSON时,它失败并出现错误.我不想手动打开58+ JSON文件并在没有BOM的情况下转换为UTF-8.

knu*_*nut 34

使用ruby> = 1.9.2,您可以使用该模式 r:bom|utf-8

这应该工作(我没有与json结合测试):

json = nil #define the variable outside the block to keep the data
File.open('file.txt', "r:bom|utf-8"){|file|
  json = JSON.parse(file.read)
}
Run Code Online (Sandbox Code Playgroud)

如果BOM在文件中可用,则无关紧要.


安德鲁评论说,File#rewind不能用于BOM.

如果您需要倒带功能,您必须记住位置并替换rewindpos=:

#Prepare test file
File.open('file.txt', "w:utf-8"){|f|
  f << "\xEF\xBB\xBF" #add BOM
  f << 'some content'
}

#Read file and skip BOM if available
File.open('file.txt', "r:bom|utf-8"){|f|
  pos =f.pos
  p content = f.read  #read and write file content
  f.pos = pos   #f.rewind  goes to pos 0
  p content = f.read  #(re)read and write file content
}
Run Code Online (Sandbox Code Playgroud)


Abe*_*Abe 20

因此,解决方案是通过gsub进行搜索并替换BOM!我强制将字符串编码为UTF-8,并强制将正则表达式模式编码为UTF-8.

通过查看http://self.d-struct.org/195/howto-remove-byte-order-mark-with-ruby-and-iconvhttp://blog.grayproductions,我得出了一个解决方案.净/文章/ ruby_19s_string

def read_json_file(file_name, index)
  content = ''
  file = File.open("#{file_name}\\game.json", "r") 
  content = file.read.force_encoding("UTF-8")

  content.gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '')

  json = JSON.parse(content)

  print json
end
Run Code Online (Sandbox Code Playgroud)

  • 我建议`sub!(/ ^\xEF\xBB\xBF /,'')`因为BOM只在字符串的开头出现一次. (11认同)
  • @Ryan我认为@Jan只是意味着使用`sub`而不是`gsub`,但不一定意味着删除`force_encoding`。 (3认同)

小智 8

您也可以使用File.readCSV.read方法指定编码,但不指定read模式.

File.read(path, :encoding => 'bom|utf-8')
CSV.read(path, :encoding => 'bom|utf-8')
Run Code Online (Sandbox Code Playgroud)


And*_*rtz 5

如果只读取一次文件,则“ bom | UTF-8”编码效果很好,但是,就像我在代码中所做的那样,如果调用File#rewind则失败。为了解决这个问题,我做了以下工作:

def ignore_bom
  @file.ungetc if @file.pos==0 && @file.getc != "\xEF\xBB\xBF".force_encoding("UTF-8")
end
Run Code Online (Sandbox Code Playgroud)

这似乎运作良好。不确定是否要寻找其他类似类型的字符,但是可以很容易地将它们内置到此方法中,您可以在倒带或打开时随时调用它们。