当我尝试在包含撇号的Ruby字符串上调用.reverse时,它会将它们更改为\231\200?
。因此,对于包含s’tI
调用反向的错误顺序的字符串会导致It\231\200?s
,而不是It's
。任何想法?
我猜这与多字节安全有关?有解决办法吗?
答案 0 :(得分:4)
这在ruby 1.9中运行正常,它正确处理unicode:
>> "s’tI".reverse
=> "It’s"
在ruby 1.8中断了,因为它对unicode字符串没有相同的支持,并且那些撇号是非1字节的ascii字符,它们是多字节unicode字符(例如,当编码为UTF-8时)
答案 1 :(得分:0)
问题是你的字符串使用二进制字符而不是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"
答案 2 :(得分:0)
正如其他人已经解释过你正在处理utf-8,因此一些字符由多个字节表示。还有一些东西,如组合字符,代理对等。红宝石1.8的逐字节反转忽略所有这一切,所以搞砸了。
Ruby 1.9确实理解字符串编码,但是如果你坚持使用ruby 1.8,rails就有自己的系统来处理utf8 - 你可以在一个字符串上调用mb_chars
并找回一些看起来像是string,行为类似于字符串,但以精通unicode的方式实现reverse
,downcase
等方法。例如,您可以
reversed_string = string.mb_chars.reverse