Ruby,“match”:UTF-8中无效的字节序列

6

我遇到了UTF-8编码的问题。我已经阅读了一些相关文章,但仍然无法正常工作。

以下是我的代码:

#!/bin/env ruby
#encoding: utf-8

def determine
  file=File.open("/home/lala.txt")          
  file.each do |line|           
    puts(line)
    type = line.match(/DOG/)
    puts('aaaaa')

    if type != nil 
      puts(type[0])
      break
    end        

  end
end

以下是我的文件的前三行:
;?lalalalal60000065535-1362490443-0000006334-0000018467-0000000041en-lalalalallalalalalalalalaln Cell Generation
text/lalalalala1.0.0.1515
text/lalalala�DOG

当我运行这段代码时,它在读取文件的第三行(也就是dog所在的位置)时显示了一个错误:
;?lalalalal60000065535-1362490443-0000006334-0000018467-0000000041en-lalalalallalalalalalalalaln Cell Generation
aaaaa

text/lalalalala1.0.0.1515
aaaaa

text/lalalala�DOG
/home/kik/Desktop/determine2.rb:16:in `match': invalid byte sequence in UTF-8 (ArgumentError)

但是,如果我只运行以下内容的确定函数:
#!/bin/env ruby
#encoding: utf-8

    def determine
    type="text/lalalala�DOG".match(/DOG/)
    puts(type)
end

它工作得非常完美。

那里出了什么问题? 提前感谢!

编辑: 文件中的第三行是:

text/lalalal»DOG

但是,当我在Ruby中打印文件的第三行时,它会显示为:

text/lalalala�DOG

编辑2:

这种格式也是为了支持本地化而开发的。文件中存储的字符串以2个字节的UNICODE字符形式存储。文件的格式是二进制文件,数据以网络位序(大端格式)存储。


@Linuxios 如果我在代码中没有加 #encoding :utf-8,我仍然会收到一个“UTF-8 中的无效字节序列”的错误消息。如果我运行代码 type="text/lalalala�DOG".match(/DOG/),它可以正常工作。 - Alina
1
在你的评论中,那个字符对我来说是无效的。如果你有无效的UTF-8序列,那么字符串就会受损,一些方法会生成像这样的异常。 - tadman
我不确定你从哪里得到这个字符,但它可能不符合UTF-8规范。当我将该字符复制并粘贴到irb中时,它显示为"\U+FFEF\U+FFBF\U+FFBD" - tadman
@tadman 这个字符显示为 [239,191,189]。我查看了文件本身,第三行看起来是: lalala»DOG 但是当我在 Ruby 中打印这一行时,它显示为 lalala�DOG。 - Alina
1
如果您能确定文件的编码方式,就可以以正确的方式打开它。它可能是ISO-1252或ISO-8859-1。如果我在文件中放置 »,在UTF-8中它会被编码为字节 [197, 187],而不是您得到的内容。您所拥有的可能是无效的。 - tadman
显示剩余8条评论
3个回答

3

我相信 @Amadan 的答案接近了,但是他的回答有些颠倒了。我会这样做:

File.open("/home/lala.txt", "r:ASCII-8BIT")

该字符不符合UTF-8标准,但就您的需求而言,似乎8位ASCII码也可以正常工作。据我了解,当您仅使用字符串时,Ruby默认使用该编码方式,因此可以正常工作。

更新:根据您最新的评论,听起来这是您需要的内容:

File.open("/home/lala.txt", "rb:UTF-16BE")

它能工作,我的意思是我没有收到错误信息,但是type = line.match(/DOG/)不起作用。它在文件中找不到单词DOG。 - Alina
未能工作:5:在“initialize”中:ASCII不兼容的编码需要binmode(ArgumentError) 来自/home/kik/Desktop/determine2.rb的5:在“打开”中 - Alina
@Katja:我认为这意味着你需要在那里加上一个 b;我刚刚更新了我的答案以反映这一点。 - Darshan Rivka Whittle
@DarshanComputing 再次出现错误:`match': UTF-16BE 中的无效字节序列 (ArgumentError)。 - Alina
那么,你的信息是错误的;它并不是大端 UTF-16。也许是生成文件的代码中有一个bug。 - Darshan Rivka Whittle

1
尝试使用这个:

File.open("/home/lala.txt", "r:UTF-8")

似乎存在某个阶段使用了错误的编码。 #encoding :utf 仅指定源文件的编码,影响了字面字符串的解释方式,但对于 File.open 使用的编码没有影响。


-1

少量文件的简单解决方案:

@Katja 在某个文本编辑器中打开文件,然后点击“另存为”选项,将其格式更改为UTF-8并点击“确定”。弹出窗口将显示替换或创建新文件。替换现有文件即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接