web-dev-qa-db-ja.com

UTF-8でエンコードされたファイルからBOMを削除する方法はありますか?

UTF-8でエンコードされたファイルからBOMを削除する方法はありますか?

すべてのJSONファイルがUTF-8でエンコードされていることは知っていますが、JSONファイルを編集したデータ入力者がBOMを使用してUTF-8として保存しました。

Rubyスクリプトを実行してJSONを解析すると、エラーで失敗します。58以上のJSONファイルを手動で開いて、BOMなしでUTF-8に変換したくありません。

30
Abe

したがって、解決策は、gsubを介してBOMで検索と置換を行うことでした。文字列のエンコードをUTF-8に強制し、正規表現パターンをUTF-8でエンコードするように強制しました。

http://self.d-struct.org/195/howto-remove-byte-order-mark-with-Ruby-and-iconv と-を見て解決策を導き出すことができました。 http://blog.grayproductions.net/articles/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
20
Abe

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)
}

BOMがファイルで使用可能かどうかは関係ありません。


Andrewは、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
}
33
knut

File.readおよびCSV.readメソッドを使用してエンコードを指定することもできますが、readモードは指定しません。

File.read(path, :encoding => 'bom|utf-8')
CSV.read(path, :encoding => 'bom|utf-8')
8
Tim Uruski

「bom | UTF-8」エンコーディングは、ファイルを1回だけ読み取る場合はうまく機能しますが、コードで行っていたようにFile#rewindを呼び出すと失敗します。これに対処するために、私は次のことを行いました。

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

これはうまくいくようです。他に注意すべき同様のタイプの文字があるかどうかはわかりませんが、このメソッドに簡単に組み込むことができ、巻き戻したり開いたりするたびに呼び出すことができます。

5
Andrew Schwartz

私のために働いたutf-8bomバイトのサーバー側のクリーンアップ:

csv_text.gsub!("\xEF\xBB\xBF".force_encoding(Encoding::BINARY), '')
1
UdiP