Как убрать непечатаемые / невидимые символы в ruby?

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

Например, они могут иметь нулевую ширину без перерыва в середине строки. Например, при разборе .po файл, одной проблемной частью была строка "he is a man of god" в середине файла. Хотя все кажется правильным, проверяя его irb показывает:

 "he is a man of god".codepoints
 => [104, 101, 32, 105, 115, 32, 97, 32, 65279, 109, 97, 110, 32, 111, 102, 32, 103, 111, 100] 

Я считаю, что я знаю, что BOM есть, и я даже справляюсь с этим приятно. Однако иногда у меня есть такие символы в середине файла, так что это не BOM,

Мой текущий подход состоит в том, чтобы удалить всех персонажей, которых я нашел злыми, действительно вонючим способом:

text = (text.codepoints - CODEPOINTS_BlACKLIST).pack("U*")

Самое близкое, что я получил, было за этим постом, который привел меня к :print: опция для регулярных выражений Однако это не было хорошо для меня:

"m".scan(/[[:print:]]/).join.codepoints
 => [65279, 109] 

поэтому возникает вопрос: как я могу удалить все непечатаемые символы из строки в ruby?

3 ответа

Решение

Ruby может помочь вам преобразовать один многобайтовый набор символов в другой. Проверьте эти результаты поиска, а также прочитайте о Ruby String's encode метод.

Также Ruby's Iconv - твой друг.

Наконец, Джеймс Грей написал серию статей, которые подробно рассказывают об этом.

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

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

Попробуй это:

>>"aaa\f\d\x00abcd".gsub(/[^[:print:]]/,'.')
=>"aaa.d.abcd"

Кодовая точка 65279 - это непрерывный пробел нулевой ширины. Обычно используется как метка порядка байтов (BOM).

Вы можете удалить его из строки с помощью:

my_new_string = my_old_string.gsub!("\xEF\xBB\xBF".force_encoding("UTF-8"), '')

Быстрый способ проверить, есть ли у вас какие-либо невидимые символы, - это проверить длину строки, если она больше, чем вы можете видеть в IRB, вы это делаете.

У меня также была та же проблема в ROR версии 3.9.3, и я использовал Visual Studio 2010 в качестве редактора. Блокнот ++ решил мою проблему.

Если вы используете Notepad++, и проблема в файле UTF-8:

  1. Открыть файл
  2. В меню "Кодирование" выберите "Кодировать в UTF-8 без спецификации", как показано на скриншоте.

Снимок экрана, где он показывает вышеупомянутый пункт меню

Для более подробной информации см. Это

Другие вопросы по тегам