加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 在字符串编码中猜测日志文件中的字节流

发布时间:2020-12-17 02:31:04 所属栏目:百科 来源:网络整理
导读:tl; dr summary:给定一个字节流表示未知编码中的字符串,我应该尝试解码字节以及以什么顺序解释字节以获得找到“正确”编码的最佳机会? 问题的例子 我有一个我碰巧知道的文件arrows.txt已经使用UTF-8保存,单字符内容为?.如果我假装我不知道该文件的编码是什
tl; dr summary:给定一个字节流表示未知编码中的字符串,我应该尝试解码字节以及以什么顺序解释字节以获得找到“正确”编码的最佳机会?

问题的例子

我有一个我碰巧知道的文件arrows.txt已经使用UTF-8保存,单字符内容为?.如果我假装我不知道该文件的编码是什么,Windows上的以下Ruby代码将失败:

s = IO.read('foo.txt')
p s.encoding,#=> #<Encoding:IBM437>
  s.valid_encoding?,#=> true
  s.chars.to_a       #=> ["xE2","x87","x88"]

它’失败’因为它告诉我文件实际上有内容Γ?ê,并且一切都很好(编码是有效的).

真实世界情景

我有Nginx个日志文件和Akamai日志文件,这些文件对于他们记录的查询没有任何特定的编码,我需要以UTF-8的形式处理和存储数据库中的数据.大多数时候将每行解释为UTF-8会生成一个带有有效编码的字符串,但有时却不会.

我想要求Ruby为每一行尝试各种编码,找到一个有效且可能(但当然不能保证)正确的编码.

尝试失败

我原来写了以下代码:

def guess_encoding( str,result='utf-8',*encodings )
  # Try every encoding if none were passed in
  encodings = Encoding.list if encodings.empty?

  # Keep forcing a new encoding until we find one that is valid
  unless encodings.find{ |e| str.force_encoding(e) && str.valid_encoding? }
    raise "None of the supplied encodings was valid"
  end

  # Convert from the valid encoding to the desired,replacing 'bad' characters
  str.encode(result,invalid: :replace,undef: :replace)
end

这个问题是Encoding.list中的第一个编码是ASCII-8BIT,它对所有字节流都有效.因此,如果我使用上面的代码并调用s2 = guess_encoding(s),结果就是上面我的三字节双箭头字符的字符串 .

最后,问题

我应该以什么顺序测试编码以提供第一次valid_encoding的最大机会?是正确的吗?哪些常见的编码是最常用的字节,所以我应该首先尝试它们,哪些常见的编码是完全允许的,这样我应该最后尝试?

我是否应该使用其他启发式方法来猜测正确性? (如果特定编码导致的字符数少于另一个,那么它更可能是正确的吗?)

解决方法

你可以尝试 rchardet19宝石.它“在未知字符编码中采用一系列字节,并尝试确定编码.”它还为您返回的编码提供置信度分数.它过去曾为我工作过好几次,看起来就像你想要完成的那样.

用法示例:

require 'rchardet19'
cd = CharDet.detect("some data")
# => #<struct #<Class:0x102216198> encoding="ascii",confidence=1.0>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读