1

次のようなUTF-8 16進数の文字列があります。

s = "0059006F007500720020006300720065006400690074002000680061007300200067006F006E0065002000620065006C006F00770020003500200064006F006C006C006100720073002E00200049006600200079006F00750020006800610076006500200061006E0020004100640064002D004F006E0020006F007200200042006F006E0075007300200079006F007500720020007200650073006F00750072006300650073002000770069006C006C00200077006F0072006B00200075006E00740069006C0020006500780068006100750073007400650064002E00200054006F00200074006F00700020007500700020006E006F007700200076006900730069007400200076006F006400610066006F006E0065002E0063006F002E006E007A002F0074006F007000750070"

これを実際のUTF-8文字列に変換したい。それは読むべきです:

クレジットが 5 ドルを下回りました。アドオンまたはボーナスがある場合、リソースは使い果たされるまで機能します。今すぐチャージするには、vodafone.co.nz/topup にアクセスしてください。

これは機能します:

s.scan(/.{4}/).map { |a| [a.hex].pack('U') }.join

しかし、これを行うためのより良い方法があるかどうか疑問に思っています: Encoding#convertを使用する必要があるかどうか。

4

3 に答える 3

4

余分な00s は、文字列が実際にはUTF-8 ではなく、UTF-16文字列の 16 進数表現であることを示しています。その場合、UTF-8 文字列を取得するために実行する必要がある手順は、最初に文字列を 16 進数が表す実際のバイトに変換することです (Array#packこれには を使用できます)。次に、適切なエンコーディングであるとマークします。force_encoding(UTF-16BEのように見えます)そして最後encodeにそれをUTF-8に変換するために使用します:

[s].pack('H*').force_encoding('utf-16be').encode('utf-8')
于 2015-04-25T10:37:12.797 に答える
1

文字列全体に余分なヌル文字があると思います(有効ですが無駄です)が、試すことができます:

[s].pack('H*').force_encoding('utf-8')

ただし、「クレジットが 5 ドルを下回りました」と表示されます...

文字列は で出力putsされますが、文字列がダンプされるときに端末ですべての Unicode 文字を読み取ることができません。

于 2015-04-25T07:05:18.503 に答える
1

これを他の奇妙にエンコードされた文字列で使用する場合は、先頭のバイトのパディングを解除できます。

[s.gsub(/..(..)/,'\1')].pack('H*')

またはそれらを使用します:

s.gsub(/..../){|p|p.hex.chr}

Encoding::Converter を使いたい場合

ec = Encoding::Converter.new('UTF-16BE','UTF-8')     # save converter for reuse
ec.convert( [s].pack('H*') )                         # or:  ec.convert [s].pack'H*'
于 2015-04-25T07:18:21.983 に答える