7

IRB では、次のことを試しています。

1.9.3p194 :001 > foo = "\xBF".encode("utf-8", :invalid => :replace, :undef => :replace)
 => "\xBF" 
1.9.3p194 :002 > foo.match /foo/
ArgumentError: invalid byte sequence in UTF-8
from (irb):2:in `match'

何がうまくいかないのですか?

4

3 に答える 3

22

"\xBF"はそれがUTF-8でエンコードされているとすでに考えているencodeと思います.

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

\xBFは有効な UTF-8 ではないため、これはもちろんナンセンスです。しかし、 の 3 つの引数形式を使用すると、次のようになりますencode

encode(dst_encoding, src_encoding [, options] ) → str

[...] 2 番目の形式は、strトランスコードされた from src_encodingtoのコピーを返しますdst_encoding

encode文字列がそのエンコーディングであると考えているものを無視し、それをバイナリデータとして扱うように指示することで、問題を強制できます。

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

上からUTF-8だと思うsのはどこだ。"\xBF"

force_encodingon を使用しsて強制的にバイナリにしてから、2 つの引数を使用することもできます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)
=> "�"
于 2012-05-05T21:50:59.967 に答える
5

使用できるASCII文字のみを使用している場合

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

しかし、ascii では無効な有効な UTF8 文字で同じアプローチを使用するとどうなるでしょうか。

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

ええとああ!frío をアクセントのままにしておきます。有効な UTF8 文字を保持するオプションを次に示します。

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

また、Ruby 2.1 には、scrubこの問題を解決するという新しいメソッドがあります。

>> "¡Hace \xBF mucho frío!".scrub
=> "¡Hace � mucho frío!"
>> "¡Hace \xBF mucho frío!".scrub('')
=> "¡Hace  mucho frío!"
于 2014-11-30T03:19:20.623 に答える
2

これは、明示的なコード ページを使用してソース テキスト ファイルを読み取ると修正されます。

File.open( 'thefile.txt', 'r:iso8859-1' )
于 2013-03-19T18:41:41.047 に答える