如何检查字符是否为utf-8

时间:2011-12-26 12:05:57

标签: ruby-on-rails ruby

如何通过ruby | ror?

检查字符集是否为utf-8编码

3 个答案:

答案 0 :(得分:10)

在Ruby和其他任何地方都没有明确的方法可以做到这一点:

str = 'foo' # start with a simple string
# => "foo" 
str.encoding
# => #<Encoding:UTF-8> # which is UTF-8 encoded
str.bytes.to_a
# => [102, 111, 111] # as you can see, it consists of three bytes 102, 111 and 111
str.encode!('us-ascii') # now we will recode the string to 8-bit us-ascii encoding
# => "foo" 
str.encoding
# => #<Encoding:US-ASCII> 
str.bytes.to_a
# => [102, 111, 111] # see, same three bytes
str.encode!('windows-1251') # let us try some cyrillic
# => "foo" 
str.encoding
# => #<Encoding:Windows-1251> 
str.bytes.to_a
# => [102, 111, 111] # see, the same three again!

当然,您可以对文本进行一些统计分析,并消除文本无效的编码,但从理论上讲,这不是可解决的问题。

答案 1 :(得分:10)

检查UTF-8有效性

对于大多数多字节编码,可以以编程方式检测无效字节序列。由于Ruby默认情况下将所有字符串视为UTF-8,因此您可以检查字符串是否在有效UTF-8中给出:

# encoding: UTF-8
# -------------------------------------------
str = "Partly valid\xE4 UTF-8 encoding: äöüß"

str.valid_encoding?
   # => false

str.scrub('').valid_encoding?
   # => true

转换编码

此外,如果字符串无效UTF-8编码,但您知道实际的字符编码,则可以将字符串转换为UTF-8编码。

示例
有时,您最终会遇到输入文件编码为UTF-8CP1252(a.k.a。Windows-1252)的情况。 检查它是哪种编码并转换为UTF-8(如有必要):

# encoding: UTF-8
# ------------------------------------------------------
test = "String in CP1252 encoding: \xE4\xF6\xFC\xDF"
File.open( 'input_file', 'w' ) {|f| f.write(test)}

str  = File.read( 'input_file' )

unless str.valid_encoding?
  str.encode!( 'UTF-8', 'CP1252', invalid: :replace, undef: :replace, replace: '?' )
end #unless
   # => "String CP1252 encoding: äöüß"

=======
备注

  • 以编程方式可以检测大多数多字节编码,如UTF-8(在Ruby中,see: #valid_encoding?),具有很高的可靠性。在仅16个字节之后,随机字节序列的有效概率为UTF-8 is only 0.01%。 (相比之下,依靠UTF-8 BOM

  • 但是,不可能以编程方式检测({1}}或CP1252等单字节编码的有效性。因此,上面的代码片段不起作用,即检测字符串是否有效ISO-8859-1编码。

  • 尽管UTF-8作为网络中的默认编码越来越受欢迎,但CP1252和其他CP1252口味在西方国家仍然非常受欢迎,特别是在北美。请注意,那里有几个单字节编码非常相似,但与Latin1(a.k.a。CP1252)略有不同。示例:Windows-1252ISO-8859-1

答案 2 :(得分:1)

"your string".encoding
 # => #<Encoding:UTF-8>

或者如果您想以编程方式进行,

"your string".encoding.name == "UTF-8"
 # => true