В Ruby 1.9.3 можно использовать String.encode, чтобы «игнорировать» недопустимые последовательности UTF-8. Вот фрагмент кода, который будет работать как в 1.8 ( iconv ), так и в 1.9 ( String # encode ):
require 'iconv' unless String.method_defined?(:encode)
if String.method_defined?(:encode)
file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
file_contents = ic.iconv(file_contents)
end
или, если у вас действительно проблемный ввод, вы можете выполнить двойное преобразование из UTF-8 в UTF-16 и обратно в UTF-8:
require 'iconv' unless String.method_defined?(:encode)
if String.method_defined?(:encode)
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
file_contents.encode!('UTF-8', 'UTF-16')
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
file_contents = ic.iconv(file_contents)
end