2012-02-03 21 views
4

ウェブからソースを取得します。素材のエンコーディングが100%UTF8バイトシーケンスでない場合があります。私はiconvを使って、これらのシーケンスを静かに無視してきれいな文字列を取得します。廃止されたiconvをString#にエンコードして無効なUTF8修正をエンコードする方法

@iconv = Iconv.new('UTF-8//IGNORE', 'UTF-8') 
valid_string = @iconv.iconv(untrusted_string) 

しかしiconvは廃止されましたが、廃止予定の警告が多いようです。 iconvのは、将来的に廃止される予定

、文字列#エンコードに

を使用し、私はString#encode年代に:invalid:replaceオプションを使用して、それを変換しようとしたが、それが動作していないようです(つまり、間違ったバイト列削除されていない)。このためにString#encodeを使用する正しい方法は何ですか?

+0

私はあなたが試みていることは非常に危険だと思います。テキストエンコーディングは妊娠と似ています。あなたはUTF8を持っているか、そうではありません。あなたはUTF8の "ビット"を持つことはできません。エラーがある場合、中止する必要があります。そうしないと、悪意を持って準備された文字列による攻撃の影響を受けます。 –

+0

私はクローラを書いていますが、そこには無効なページがあります。だからバイトをきれいにするだけで済む。 – lulalala

答えて

6

疑問があるように見えるものを持っていますそれを行う2つの最善の方法が、マルティンは理解できたbあなたの答えに2番目のアプローチをコピーすると誤った変更になります。 .encode( 'UTF-8'、<オプション>).encode( 'UTF-8')は機能しません。他の質問の元の答えに示されているように、鍵は、別のにエンコードし、次にのエンコーディングを行い、その後UTF-8に戻ります。元の文字列がすでにルビの内部でUTF-8としてフラグが立てられている場合、ルビはそれを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" 
+0

実際にあなたは正しいです。私がUTF-8を使っているだけで、文字列にgsubを使用すると、 "無効なエンコーディング"エラーが発生します。しかし、あなたの答えはそれを修正します。私はより早期に不合理なテストをしたに違いない。 – lulalala

7

これは、この質問に回答されていますマルタインはにリンクされていること

Is there a way in ruby 1.9 to remove invalid byte sequences from strings?

使用のいずれか

untrusted_string.chars.select{|i| i.valid_encoding?}.join 

または

untrusted_string.encode('UTF-8', :invalid => :replace, :replace => '').encode('UTF-8') 
+0

答えは、エンコードの変更またはエンコードは何もしないと言います。したがって、 'wtf.encode( 'UTF-8'、blah blah).encode( 'UTF-8')'を書くとき、最初のエンコードはここでは何の効果もありません。 – nurettin

関連する問題