Почему ruby ​​не обнаруживает неверную кодировку, в то время как mysql это делает? - PullRequest
3 голосов
/ 09 мая 2011

Я вытаскиваю несколько RSS-каналов с YouTube, которые имеют недопустимый UTF8. Я могу создать аналогичную рубиновую строку, используя

bad_utf8 = "\u{61B36}"
bad_utf8.encoding # => #<Encoding:UTF-8>
bad_utf8.valid_encoding? # => true

Руби считает, что это правильная кодировка UTF-8, и я почти уверен, что это не так.

При разговоре с Mysql я получаю сообщение об ошибке вроде

require 'mysql2'
client = Mysql2::Client.new(:host => "localhost", :username => "root")
client.query("use test");

bad_utf8 = "\u{61B36}"
client.query("INSERT INTO utf8 VALUES ('#{moo}')")

# Incorrect string value: '\xF1\xA1\xAC\xB6' for column 'string' at row 1 (Mysql2::Error)

Как я могу обнаружить или исправить эти недопустимые типы кодировок, прежде чем отправлять их в MySQL?

Ответы [ 2 ]

2 голосов
/ 04 апреля 2012

Я не полагаюсь на встроенный в Ruby String.valid_encoding ?, потому что также возможно следующее:

irb
1.9.3-p125 :001 > bad_utf8 = "\u{0}"
 => "\u0000" 
1.9.3-p125 :002 > bad_utf8.valid_encoding?
 => true 
1.9.3-p125 :003 > bad_utf8.encoding
 => #<Encoding:UTF-8>

Это действительно UTF-8 (ссылка: https://en.wikipedia.org/wiki/Utf8),, но я обнаружил, что наличие символа NULL в строке часто является подсказкой к предыдущей ошибке преобразования (например, при перекодировании из недопустимой информации кодирования, найденной в html). страницы).

Я создал свою собственную функцию проверки для «Modified UTF-8», которая может принимать параметр: bmp_only для ограничения проверки на Базовую многоязычную плоскость (0x1-0xffff). Этого должно быть достаточно для большинства современных языков (ссылка: https://en.wikipedia.org/wiki/Unicode_plane).

Найдите валидатор здесь: https://gist.github.com/2295531

1 голос
/ 09 мая 2011

возможно, потому что кодовая точка не лежит в базовой многоязычной плоскости это единственные символы, которые MySQL разрешает в своем наборе символов "utf8".

Более новые версии mysql имеют другой набор символов, называемый "utf8mb4", который поддерживает символы Юникода вне BMP .

Но вы, вероятно, не хотите этим пользоваться. Тщательно рассмотрите ваши варианты использования. Немногие настоящие человеческие языки (если есть) используют символы вне BMP.

...