Ruby 2.0.0 String#Match ArgumentError:неверная последовательность байтов в UTF-8

StackOverflow https://stackoverflow.com//questions/24036821

Вопрос

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

# @raw_response comes from user and contains invalid UTF-8
# for example: @raw_response = "\xBF"  
regex.match(@raw_response)
ArgumentError: invalid byte sequence in UTF-8

Было задано множество подобных вопросов, и результатом, похоже, является кодирование или принудительное кодирование строки.Однако ни один из них не работает для меня:

regex.match(@raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8

или

regex.match(@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8

Это ошибка Ruby 2.0.0 или я что-то упускаю?

Что странно, так это то, что кодирование выглядит правильно, но совпадение продолжает вызывать исключение:

@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
 => #<Encoding:UTF-8>
Это было полезно?

Решение

В Руби 2.0 encode метод является неактивным при кодировании строки в ее текущую кодировку:

Обратите внимание, что преобразование из кодировки enc в ту же кодировку enc является недействующей операцией, т.е.получатель возвращается без каких-либо изменений, и никаких исключений не возникает, даже если есть недопустимые байты.

Это изменилось в версии 2.1, в которой также был добавлен scrub метод как более простой способ сделать это.

Если вы не можете обновиться до версии 2.1, вам придется закодировать другую кодировку и вернуться обратно, чтобы удалить недопустимые байты, например:

if ! s.valid_encoding?
  s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end

Другие советы

С тех пор, как вы используете Rails, а не просто Ruby, вы также можете использовать tidy_bytesЭто работает с Ruby 2.0, а также, вероятно, даст вам разумные данные, а не только для замены символов.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top