Ruby 2.0.0 String#Match ArgumentError:UTF-8中的无效字节序列

Tom*_*ssi 26 ruby ruby-on-rails ruby-2.0 ruby-on-rails-4

我看到了很多,并没有想出一个优雅的解决方案.如果用户输入包含无效的字节序列,我需要能够让它不引发异常.例如:

# @raw_response comes from user and contains invalid UTF-8
# for example: @raw_response = "\xBF"  
regex.match(@raw_response)
ArgumentError: invalid byte sequence in UTF-8
Run Code Online (Sandbox Code Playgroud)

已经提出了许多类似的问题,结果似乎是对字符串进行编码或强制编码.然而,这些对我来说都不起作用:

regex.match(@raw_response.force_encoding("UTF-8"))
ArgumentError: invalid byte sequence in UTF-8
Run Code Online (Sandbox Code Playgroud)

要么

regex.match(@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?"))
ArgumentError: invalid byte sequence in UTF-8
Run Code Online (Sandbox Code Playgroud)

这是Ruby 2.0.0的错误还是我错过了什么?

奇怪的是它似乎正确编码,但匹配继续引发异常:

@raw_response.encode("UTF-8", :invalid=>:replace, :replace=>"?").encoding
 => #<Encoding:UTF-8>
Run Code Online (Sandbox Code Playgroud)

mat*_*att 46

在Ruby 2.0中,当将字符串编码为其当前编码时,该encode方法是无操作的:

请注意,从编码enc到相同编码的转换enc是无操作,即接收器在没有任何更改的情况下返回,并且即使存在无效字节也不会引发异常.

这在2.1中有所改变,它还添加了该scrub方法作为一种更简单的方法.

如果您无法升级到2.1,则必须编码为不同的编码并返回以删除无效字节,例如:

if ! s.valid_encoding?
  s = s.encode("UTF-16be", :invalid=>:replace, :replace=>"?").encode('UTF-8')
end
Run Code Online (Sandbox Code Playgroud)


Yog*_*ogh 7

既然你使用Rails而不仅仅是Ruby,你也可以使用tidy_bytes.这适用于Ruby 2.0,也可能会为您提供合理的数据,而不仅仅是替换字符.

  • 我觉得有必要给你一个迟来的感谢。早点知道“tidy_bytes”会让我免于许多小时的挫败感……不敢相信我直到现在才听说过它。 (2认同)