2012-05-05 29 views

Trả lời

21

Tôi đoán rằng "\xBF" đã nghĩ rằng nó được mã hóa theo UTF-8 vì vậy khi bạn gọi encode, nó nghĩ rằng bạn đang cố gắng để mã hóa một chuỗi UTF-8 trong UTF-8 và không có gì:

>> s = "\xBF" 
=> "\xBF" 
>> s.encoding 
=> #<Encoding:UTF-8> 

\xBF không hợp lệ UTF-8 vì vậy, điều này tất nhiên là vô lý. Nhưng nếu bạn sử dụng hình thức ba đối số của encode:

mã hóa (dst_encoding, src_encoding [, tùy chọn]) → str

[...] Các hình thức thứ hai trả về một bản sao của str chuyển mã từ src_encoding đến dst_encoding.

Bạn có thể buộc các vấn đề bằng cách nói encode để bỏ qua những gì các chuỗi nghĩ mã hóa của nó là gì và đối xử với nó như là dữ liệu nhị phân:

>> foo = s.encode('utf-8', 'binary', :invalid => :replace, :undef => :replace) 
=> "�" 

đâu s"\xBF" mà nghĩ rằng nó là UTF-8 từ ở trên.

Bạn cũng có thể sử dụng force_encoding trên s để buộc nó phải nhị phân và sau đó sử dụng hai tham số encode:

>> s.encoding 
=> #<Encoding:UTF-8> 
>> s.force_encoding('binary') 
=> "\xBF" 
>> s.encoding 
=> #<Encoding:ASCII-8BIT> 
>> foo = s.encode('utf-8', :invalid => :replace, :undef => :replace) 
=> "�" 
+0

Cảm ơn! Sử dụng 'ascii' làm từ mã hóa cũng hoạt động. – drewinglis

+1

@drewinglis: Tôi thích sự giải thích về "nhị phân" (là bí danh cho "ascii-8bit"), "ascii" không giống hệt nhau. –

2

này là cố định nếu bạn đọc các tập tin văn bản nguồn trong việc sử dụng một trang mã rõ ràng:

File.open('thefile.txt', 'r:iso8859-1') 
2

Nếu bạn chỉ làm việc với các nhân vật ascii bạn có thể sử dụng

>> "Hello \xBF World!".encode('utf-8', 'binary', :invalid => :replace, :undef => :replace) 
=> "Hello � World!" 

Nhưng điều gì sẽ xảy ra nếu chúng tôi sử dụng phương pháp tương tự với các nhân vật UTF8 hợp lệ mà không có giá trị trong ascii

>> "¡Hace \xBF mucho frío!".encode('utf-8', 'binary', :invalid => :replace, :undef => :replace) 
=> "��Hace � mucho fr��o!" 

Uh oh! Chúng tôi muốn frío vẫn còn với giọng. Dưới đây là một lựa chọn mà giữ các nhân vật UTF8 hợp lệ

>> "¡Hace \xBF mucho frío!".chars.select{|i| i.valid_encoding?}.join 
=> "¡Hace mucho frío!" 

Cũng trong Ruby 2.1 có một phương pháp mới được gọi là scrub rằng giải quyết vấn đề này

>> "¡Hace \xBF mucho frío!".scrub 
=> "¡Hace � mucho frío!" 
>> "¡Hace \xBF mucho frío!".scrub('') 
=> "¡Hace mucho frío!" 
Các vấn đề liên quan