Как удалить 4-байтовые символы utf-8 в Ruby?

Поскольку MySQL utf8 не поддерживает 4-байтовые символы, я ищу способ обнаружить и удалить любые 4-байтовые символы utf8 из строки в Ruby. Я понимаю, что могу обновить свою таблицу, чтобы использовать utf8m4, но по нескольким причинам это невозможно или не является желаемым решением.

Простое кодирование строки в ASCII удалит эти символы, но также удалит все другие символы, отличные от ASCII, что нехорошо.


person JZC    schedule 10.05.2013    source источник


Ответы (2)


В Ruby 1.9.3 у меня работает следующее:

input.each_char.select{|c| c.bytes.count < 4 }.join('')

Например:

input = "hello \xF0\xA9\xB6\x98 world"                  # includes U+29D98
input.each_char.select{|c| c.bytes.count < 4 }.join('') # 'hello  world'
person John Ledbetter    schedule 10.05.2013
comment
Спасибо! Теперь кажется очевидным, что вы это предложили. Я так глубоко задумался о кодировках, что не подумал просто посмотреть на количество байтов каждого символа. - person JZC; 10.05.2013
comment
Как производительность этого с длинной строкой? 5000+ символов? - person Arnold Roa; 17.07.2014
comment
спасибо, спасибо, спасибо ... лично я не беспокоюсь о производительности, на данный момент я рад иметь рабочее решение - person steve; 14.04.2016

Другой вариант (протестирован в ruby ​​2.7) — использовать регулярное выражение с gsub:

input = "hello \xF0\xA9\xB6\x98 world"    # includes U+29D98
input.gsub(/[\u{10000}-\u{10FFFF}]/, "?") # 'hello ? world'
person James Healy    schedule 10.07.2021