Подтвердить что ты не робот

Есть ли способ удалить спецификацию из кодированного файла UTF-8?

Есть ли способ удалить спецификацию из кодированного файла UTF-8?

Я знаю, что все мои JSON файлы закодированы в UTF-8, но человек ввода данных, который редактировал файлы JSON, сохранил его как UTF-8 с спецификацией.

Когда я запускаю свои скрипты Ruby для разбора JSON, он не работает с ошибкой. Я не хочу вручную открывать 58+ JSON файлов и конвертировать в UTF-8 без спецификации.

4b9b3361

Ответ 1

Итак, решение заключалось в том, чтобы выполнять поиск и замену в спецификации через gsub! Я принудительно кодировал строку в 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 p >

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

Ответ 2

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

Это не имеет значения, если спецификация доступна в файле или нет.


Андрей заметил, что File#rewind не может использоваться с спецификацией.

Если вам нужна функция перемотки, вы должны запомнить позицию и заменить rewind на pos=:

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

Ответ 3

Вы также можете указать кодировку с помощью методов File.read и CSV.read, но вы не укажете режим read.

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

Ответ 4

кодировка "bom | UTF-8" работает хорошо, если вы только читаете файл один раз, но сбой, если вы когда-либо вызываете "Перематывать файл", как я это делал в своем коде. Чтобы решить эту проблему, я сделал следующее:

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

который, кажется, работает хорошо. Не уверен, есть ли другие аналогичные типы символов, но они могут быть легко встроены в этот метод, который можно вызвать в любое время, когда вы перематываете или открываете.