Есть ли способ в ruby ​​​​1.9 удалить недопустимые последовательности байтов из строк?

Предположим, у вас есть строка типа "€foo\xA0" в кодировке UTF-8. Есть ли способ удалить недопустимые последовательности байтов из этой строки? ( так что вы получаете "€foo" )

В ruby-1.8 вы могли использовать Iconv.iconv('UTF-8//IGNORE', 'UTF-8', "€foo\xA0"), но теперь это устарело. "€foo\xA0".encode('UTF-8') ничего не делает, так как это уже UTF-8. Я пытался:

"€foo\xA0".force_encoding('BINARY').encode('UTF-8', :undef => :replace, :replace => '')

что дает

"foo"

Но при этом также теряется действительный многобайтовый символ €


person StefanH    schedule 03.01.2012    source источник


Ответы (4)


Руби 2.0 и 1.9.3

"€foo\xA0".encode(Encoding::UTF_8, Encoding::UTF_8, :invalid => :replace)

Руби 2.1+

"€foo\xA0".scrub
person Ethan J. Brown    schedule 26.04.2017

person    schedule
comment
Он не удаляет \xF1 в этой строке "eEspa\xF1a;FB" - person Dorian; 24.09.2014
comment
@Dorian, на консоли IRB 1.9.3 "eEspa\xF1a;FB".chars.select{|i| i.valid_encoding?}.join возвращает "eEspaa;FB" ... вы не понимаете такого поведения или я неправильно понял? - person acobster; 20.03.2015

person    schedule
comment
У меня сложилось впечатление, что он имеет больший набор символов, чем UTF-8, что означает, что вы не потеряете никаких действительных данных. К сожалению, следующее не работает: "€foo\xA0".encode('UTF-8', :invalid => :replace, :replace => '') потому что строка уже имеет кодировку UTF-8, поэтому она не будет повторно закодирована. - person Van der Hoorn; 29.04.2012
comment
FWIW, запустив тест на большом файле, я обнаружил, что этот метод на порядок быстрее, чем подход valid_encoding. - person jwadsack; 05.10.2012
comment
UTF-8 и UTF-16 могут представлять все символы Unicode. Единственная разница заключается в способе кодирования символов. - person Zr40; 10.11.2012
comment
UTF-32 тоже вариант, но UTF-16 работает достаточно хорошо. Для новых эмодзи может потребоваться дополнительное место. - person tadman; 13.12.2012
comment
Все кодировки UTF в равной степени способны кодировать все возможные символы Unicode; в этом отношении нет никакой разницы между UTF-8, UTF-16 и UTF-32. Единственным практическим отличием является выходной размер. - person Zr40; 02.06.2013
comment
Выдает ошибку с этой строкой: "eEspa\xF1a;FB" - person Dorian; 24.09.2014
comment
@Dorian: какая версия Ruby? - person Van der Hoorn; 06.03.2015
comment
@VanderHoorn: это был ruby ​​‹ 2.1, потому что он работает с ruby ​​2.1+ - person Dorian; 10.03.2015
comment
@Дориан: Понятно. Может ли это быть проблемой Ruby 2.0.x? Потому что я думаю, что использовал Ruby 1.9.3, когда отвечал на исходный вопрос. - person Van der Hoorn; 11.03.2015

person    schedule
comment
Это не дает ответа на вопрос. Чтобы подвергнуть критике или запросить разъяснения у автора, оставьте комментарий под его сообщением — вы всегда можете прокомментировать свои собственные сообщения, и как только у вас будет достаточно репутация, вы сможете комментировать любой пост. - person Severin; 11.10.2014
comment
@Северин, почему нет? Похоже на (неправильный) ответ на вопрос. Он удаляет всю недопустимую последовательность байтов из строки. Он просто удаляет все действительные. - person John Dvorak; 11.10.2014