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

Ruby不兼容的字符编码

发布时间:2020-12-17 03:29:21 所属栏目:百科 来源:网络整理
导读:我目前正在尝试编写一个迭代输入文件并检查网站数据的脚本.如果找到新数据,它会打印到它传递的终端,如果没有,它会告诉我它失败了.对于删除的数据,反之亦然.它一直工作正常,直到我给出的输入文件包含“?”字符.然后当 ruby到达那一行时,它会吐出一个错误: PD
我目前正在尝试编写一个迭代输入文件并检查网站数据的脚本.如果找到新数据,它会打印到它传递的终端,如果没有,它会告诉我它失败了.对于删除的数据,反之亦然.它一直工作正常,直到我给出的输入文件包含“?”字符.然后当 ruby到达那一行时,它会吐出一个错误:

PDAPWeb.rb:73:in `include?’: incompatible character encodings: UTF-8 and IBM437
(Encoding::CompatibilityError)

违规行是一个简单的检查,以查看页面上是否存在文本.

if browser.text.include? (program_name)

其中program_name变量是来自输入文件的已解析信息.在这种情况下,program_name包含前面提到的’TM’字符.

经过一些研究后,我发现在我的脚本开头添加#encoding:utf-8行可能有所帮助,但到目前为止还没有证明有用.

我将它添加到我的program_name变量中以查看它是否有用(并且它允许我的脚本无错误地运行),但现在它没有正确地找到它应该的TM字符.

program_name = record[2].gsub("n",'').force_encoding("utf-8").encode("IBM437",replace: nil)

这似乎将TM字符转换为:Γ?ó

我想也许我有IBM437和utf-8部件相反,所以我尝试了相反的

program_name = record[2].gsub("n",'').force_encoding("IBM437").encode("utf-8",replace: nil)

并且我现在在尝试运行脚本时收到此错误

PDAPWeb.rb:48:in `encode’: U+2122 from UTF-8 to IBM437 (Encoding::UndefinedConve
rsionError)

我使用的是ruby 1.9.3p392(2013-02-22),我不确定是否应该升级,因为这是我公司安装的标准版本.

我的编码是否不正确并导致它转换TM字符有错误?

解决方法

这就是它的样子.您的输入文件包含一个?字符,它采用UTF-8编码.但是当你阅读它时,由于你没有指定编码,Ruby假定它是你系统的默认编码IBM437(你必须在Windows上).

这与此基本相同:

>> input = "?"
=> "?"
>> input.encoding
=> #<Encoding:UTF-8>
>> input.force_encoding 'ibm437'
=> "xE2x84xA2"

请注意,force_encoding不会更改实际字符串,只会更改与其关联的标签.这与您的情况相同,只有您通过不同的路线到达此处(通过阅读文件).

该网页也有一个?符号,也编码为UTF-8,但在这种情况下,Ruby的编码是正确的(Watir可能使用页面中的标题):

>> web_page = '?'
=> "?"
>> web_page.encoding
=> #<Encoding:UTF-8>

现在,当您尝试比较这两个字符串时,会出现兼容性错误,因为它们具有不同的编码:

>> web_page.include? input
Encoding::CompatibilityError: incompatible character encodings: UTF-8 and IBM437
    from (irb):11:in `include?'
    from (irb):11
    from /Users/matt/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'

如果两个字符串中的任何一个只包含ASCII字符(即代码点少于128),那么这种比较就可以了. UTF-8和IBM437都是ASCII的超集,如果它们都包含ASCII范围之外的字符,则它们只是不兼容.这就是您在输入文件具有?时才开始看到此行为的原因.

修复是告知Ruby输入文件的实际编码是什么.您可以使用已加载的字符串执行此操作:

>> input.force_encoding 'utf-8'
=> "?"

您也可以在reading the file时执行此操作,例如(有几种方法可以读取文件,它们都应该允许您明确指定编码):

input = File.read("input_file.txt",:encoding => "utf-8")
# now input will be in the correct encoding

注意,在这两个字符串中都没有被更改,它仍然包含相同的字节,但Ruby现在知道它的正确编码.

现在比较应该可行:

>> web_page.include? input
=> true

没有必要encode字符串.如果你这样做会发生什么.首先,如果您将编码更正为UTF-8,则编码为IBM437:

>> input.force_encoding("utf-8").encode("IBM437",replace: nil)
Encoding::UndefinedConversionError: U+2122 from UTF-8 to IBM437
    from (irb):16:in `encode'
    from (irb):16
    from /Users/matt/.rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'

IBM437不包含?字符,因此您无法将包含它的字符串编码为此编码而不会丢失数据.默认情况下,Ruby会在发生这种情况时引发异常.您可以使用:undef选项强制编码,但符号丢失:

>> input.force_encoding("utf-8").encode("IBM437",:undef => :replace)
=> "?"

如果你走另一条路,首先使用force_encoding到IBM437,然后编码为UTF-8,你得到字符串Γ?ó:

>> input.force_encoding("IBM437").encode("utf-8",replace: nil)
=> "Γ?ó"

就Ruby而言,该字符串已经采用IBM437编码,因此force_encoding不会执行任何操作. TMF的UTF-8表示是三个字节0xe2 0x84 0xa2,当解释为IBM437时,这些字节对应于此处看到的三个字符,然后转换为它们的UTF-8表示.

(这两个结果与您在问题中描述的内容相反,因此我的评论如上所述.我假设这只是一个复制粘贴错误.)

(编辑:李大同)

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

    推荐文章
      热点阅读