Вопрос, с которым связался Мартейн, имеет два наилучших способа сделать это, но Мартейн внес понятное, но неверное изменение, копируя второй подход к своему ответу здесь.Выполнение .encode ('UTF-8', ). Encode ('UTF-8') не работает.Как указано в исходном ответе на другой вопрос, ключ заключается в кодировании в другую кодировку , а затем обратно в UTF-8.Если ваша исходная строка уже помечена как UTF-8 во внутренних элементах ruby, тогда ruby будет игнорировать любой вызов для кодирования ее как UTF-8.
В следующих примерах я буду использовать "a # {0xFF.chr} b ".force_encoding ('UTF-8'), чтобы создать строку, которую ruby считает UTF-8, но которая содержит недопустимые байты UTF-8.
1.9.3p194 :019 > "a#{0xFF.chr}b".force_encoding('UTF-8')
=> "a\xFFb"
1.9.3p194 :020 > "#{0xFF.chr}".force_encoding('UTF-8').encoding
=> #<Encoding:UTF-8>
Обратите внимание, что кодирование в UTF-8 ничего не делает:
1.9.3p194 :016 > "a#{0xFF.chr}b".force_encoding('UTF-8').encode('UTF-8', :invalid => :replace, :replace => '').encode('UTF-8')
=> "a\xFFb"
Но кодирование во что-то другое (UTF-16) и затем обратно в UTF-8 очищает строку:
1.9.3p194 :017 > "a#{0xFF.chr}b".force_encoding('UTF-8').encode('UTF-16', :invalid => :replace, :replace => '').encode('UTF-8')
=> "ab"