如何使用gsub替换ruby中的多字节字符?

时间:2012-06-12 08:35:30

标签: ruby ruby-on-rails-3 mongodb

我在MongoDB中使用Mongoid保存记录时遇到问题,因为它们包含多字节字符。这是字符串:

a="Chris \xA5\xEB\xAE\xDFe\xA5"

我首先将其转换为BINARY然后我gsub就像这样:

a.force_encoding("BINARY").gsub(0xA5.chr,"oo")

......工作正常:

=> "Chris oo\xEB\xAE\xDFeoo"

但是,如果我使用chr,我似乎无法使用Regexp方法:

a.force_encoding("BINARY").gsub(/0x....?/.chr,"")
NoMethodError: undefined method `chr' for /0x....?/:Regexp

有同样问题的人吗?

非常感谢...

2 个答案:

答案 0 :(得分:5)

你可以用插值

来做到这一点
a.force_encoding("BINARY").gsub(/#{0xA5.chr}/,"") 

给出

"Chris \xEB\xAE\xDFe"

编辑:根据评论,这里有一个版本,它将二进制编码字符串转换为ascii表示并对该字符串执行正则表达式

a.unpack('A*').to_s.gsub(/\\x[A-F0-9]{2}/,"")[2..-3] #=>"Chris "

[2 ..- 3]最后是摆脱开头[“和尾随”]

注意:要删除特殊字符,您也可以使用

a.gsub(/\W/,"") #=> "Chris"

答案 1 :(得分:2)

实际字符串不包含文字字符\ xA5:这就是如何向您显示否则将无法打印的字符(类似于字符串包含换行符ruby时显示的情况)。

如果你想改变任何非ascii的东西,你可以这样做

a="Chris \xA5\xEB\xAE\xDFe\xA5"
a.force_encoding('BINARY').encode('ASCII', :invalid => :replace, :undef => :replace, :replace => 'oo')

首先强制字符串为二进制编码(您总是希望以字符串对其编码有效的字符串开始。二进制文件始终有效,因为它可以包含任意字节)。然后它将其转换为ASCII。通常这会引发错误,因为有些字符不知道该怎么做但我们传递的额外选项告诉它用字符'oo'替换无效/未定义的序列