ruby – 在字符串编码中猜测日志文件中的字节流
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> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- C#:如何将字符串转换为DateTime,其中字符串可以具有任何标
- 未将对象引用设置到对象的实例。未处理NullReferenceExcept
- reactjs – 在React Native项目中应忽略哪些文件夹git?
- c – 将静态访问者与静态多态性层次结合起来
- 正则表达式在ios中的应用
- Oracle 分区表 收集统计信息 参数granularity
- 使用Ajax或Easyui等框架时的Json-lib的处理方案
- postgresql – 从PSQL中的字符串中提取年份和周数时出现问题
- xcode – 如何在调试时打印Swift结构的自定义描述,而不是其
- c – OpenCV cv :: findHomography运行时错误