2015-07-07 4 views
3

У меня есть строка вроде этого "abce\xC3".sub("a","A"), когда я выполняю строку, я получаю следующую ошибку.Неверная последовательность байтов в UTF-8 Ruby

ArgumentError: invalid byte sequence in UTF-8 
    from (irb):20:in `sub' 
    from (irb):20 
    from /home/vijay/.rvm/rubies/ruby-2.0.0-p598/bin/irb:12:in `<main>' 

Может кто-нибудь помочь мне решить эту проблему.

+3

Байт «\ xC3» не является допустимым символом UTF-8. Ваша проблема возникает в некотором роде, когда вы получаете это значение из исходного кода (или ваши предположения о том, как можно манипулировать строками Ruby). Чтобы получить помощь, вам нужно будет немного объяснить, что должно представлять это значение или как оно было прочитано в вашей программе. –

+2

Откуда берется '\ xC3'? В UTF-8 это означает, что должен следовать второй байт (например, '\ xA4' для' ä'). – cremno

+0

«ITZVû - это точная строка.Я работаю. – Vijay

ответ

6

Как Арье уже ответил эту ошибку, потому что недействительные байты последовательность \xC3

Если вы используете Рубин 2.1 +, вы можете также использовать String#scrub заменить недействительные байты с заданным символом замены. Здесь:

a = "abce\xC3" 
# => "abce\xC3" 
a.scrub 
# => "abce�" 
a.scrub.sub("a","A") 
# => "Abce�" 
5

Вам нужно выяснить, что вы хотите от \xC3. Представляет ли он символ Ã?

Вы видите ошибку, так как \xC3 недопустима последовательность байтов в кодировке UTF-8 по умолчанию. Вы можете сначала исправить кодировку String (отвечая на вопрос выше), а затем выполнить замену.

"abce\xC3".force_encoding("iso-8859-1").sub('a', 'A') 

Или, если кодировка не имеет значения, скажем, вы обрабатываете последовательность байт, а не последовательность символов, вы можете заставить кодировку ASCII-8BIT.

"abce\xC3".force_encoding("ASCII-8BIT").sub('a', 'A') 
+0

как вы нашли \ xC3 is Ã? – Vijay

+2

И для преобразования строки в UTF-8 используйте '' abce \ xC3 ".force_encoding ('iso-8859-1'). Encode ('utf-8')' или - еще лучше - установите правильную кодировку при чтении строка. – Stefan

+0

@Vijay Это единственный байт, который превышает диапазон нормального кодирования ASCII, поэтому я попробовал [8-битное кодирование] (https://en.wikipedia.org/wiki/ASCII#8-bit) –

2

Что касается вашего comment/актуальная проблема:

"ITZVÃ" является содержание файла. Когда я прочитал файл.

z = File.open("x") 
z.read(5) 

Тогда выход должен быть ITZV\xC3\x83 вместо я получаю ITZV\xC3

Это происходит потому, что в UTF-8, Ã является многобайтовая характер, т.е. ваша строка имеет 5 символов, но 6 байт:

"ITZVÃ".chars #=> ["I", "T", "Z", "V", "Ã"] 
"ITZVÃ".bytes #=> [ 73, 84, 90, 86, 195, 131] 

z.read(5) реа DS 5 байт из файлов, возвращая таким образом неполную UTF-8 строку:

require 'tempfile' 

z = Tempfile.new('foo') 
z << 'ITZVÃ' 

z.rewind 
z.read(5) #=> "ITZV\xC3" 

Вы должны прочитать 6 байт вместо:

z.rewind 
z.read(6) #=> "ITZV\xC3\x83" 

Обратите внимание, что read всегда возвращает ASCII-8BIT закодированные строки , Вы должны установить другую кодировку вручную:

z.rewind 
z.read(6).force_encoding('utf-8') #=> "ITZVÃ" 
+0

Ya .... Стефан, ты прав .... спасибо, что ты помог ... – Vijay