2

私はUTF-8文字列を扱っています。文字ベースではなく、バイトベースのインデックスを使用してスライスを取得する必要があります。

Web で への参照を見つけましたString#subseq。これは のようなはずですString#[]が、バイトです。残念ながら、1.9.1 にはなっていないようです。

さて、なぜ私はそれをしたいのですか?マルチバイト文字の途中でスライスすると、無効な文字列になる可能性があります。これはひどい考えのように聞こえます。

さて、私は を使用していStringScannerますが、その内部ポインターはバイトベースであることがわかりました。ここで他のオプションを受け入れます。

これが私が今取り組んでいるものですが、かなり冗長です:

s.dup.force_encoding("ASCII-8BIT")[ix...pos].force_encoding("UTF-8")

と はどちらもixからpos来てStringScannerいるので、バイトベースです。

4

3 に答える 3

2

あなたもこれを行うことができます: s.bytes.to_a[ix...pos].join("")、しかしそれは私にはさらに難解に見えます.

回線を数回呼び出す場合、より適切な方法は次のとおりです。

class String
  def byteslice(*args)
    self.dup.force_encoding("ASCII-8BIT").slice(*args).force_encoding("UTF-8")
  end
end

s.byteslice(ix...pos)
于 2009-12-14T14:30:49.080 に答える
1

Ruby 1.9 に が追加されるString#byteslice()までは、このモンキーパッチを使用してください。

class String
  unless method_defined? :byteslice
    ##
    # Does the same thing as String#slice but
    # operates on bytes instead of characters.
    #
    def byteslice(*args)
      unpack('C*').slice(*args).pack('C*')
    end
  end
end
于 2011-02-25T08:51:57.080 に答える
1

String#bytes はあなたが望むことをしませんか? 文字列内のバイトに列挙子を返します(指摘したように、有効な文字ではない可能性があるため、数値として)

str.bytes.to_a.slice(...)
于 2009-12-14T15:05:27.340 に答える