当我尝试在包含撇号的 Ruby 字符串上调用 .reverse 时,它会将它们更改为\231\200?
. 因此,在包含s’tI
调用 reverse 的错误顺序的字符串上,结果为It\231\200?s
,而不是It's
。有任何想法吗?
我猜这与多字节安全有关?有解决办法吗?
当我尝试在包含撇号的 Ruby 字符串上调用 .reverse 时,它会将它们更改为\231\200?
. 因此,在包含s’tI
调用 reverse 的错误顺序的字符串上,结果为It\231\200?s
,而不是It's
。有任何想法吗?
我猜这与多字节安全有关?有解决办法吗?
这在 ruby 1.9 中工作正常,它正确处理 unicode:
>> "s’tI".reverse
=> "It’s"
在 ruby 1.8 中被破坏了,因为它对 unicode 字符串没有相同的支持,并且那些撇号是非 1 字节的 ascii 字符,它们是多字节的 unicode 字符(例如,当编码为 UTF-8 时)。
问题是您的字符串使用二进制字符而不是 Unicode 字符。您必须先将二进制字符串解码为 Unicode 字符串。
irb(main):001:0> "a\u9F9Cb".reverse
=> "b\u9F9Ca"
irb(main):002:0> "a\xE9\xBE\x9Cb".reverse
=> "a\x9C\xBE\xE9b"
irb(main):003:0> "a\xE9\xBE\x9Cb".force_encoding('UTF-8').reverse
=> "b\u9F9Ca"
正如其他人所解释的那样,您正在处理 utf-8,因此某些字符由一个以上的字节表示。还有诸如组合字符、代理对等之类的东西。ruby 1.8 的逐字节反转忽略了所有这些,所以把事情搞砸了。
Ruby 1.9 确实了解字符串编码,但如果你被困在 ruby 1.8 上,rails 有自己的系统来处理 utf8 - 你可以调用mb_chars
字符串并取回看起来像字符串的东西,行为像字符串但实现之类的方法reverse
,downcase
以精通 unicode 的方式。例如你可以做
reversed_string = string.mb_chars.reverse