Ruby 如何调试子字符串中的无效编码

Ruby 如何调试子字符串中的无效编码,ruby,character-encoding,Ruby,Character Encoding,如何计算字符串验证的行为令我困惑 我从文件中加载了一个数据,ruby说它的编码无效 irb(main):160:0> data = File.open("data.txt").read irb(main):171:0> data.valid_encoding? => false 如果我从数据中取出子字符串,它仍然显示为无效,尽管代码点或字节不显示任何无效字符 irb(main):172:0> s=data[11933300..11933318] => "*****

如何计算字符串验证的行为令我困惑

我从文件中加载了一个数据,ruby说它的编码无效

irb(main):160:0> data = File.open("data.txt").read
irb(main):171:0> data.valid_encoding?
=> false
如果我从数据中取出子字符串,它仍然显示为无效,尽管代码点或字节不显示任何无效字符

irb(main):172:0> s=data[11933300..11933318]
=> "******************\n"
irb(main):174:0> s.valid_encoding?
=> false
irb(main):175:0> s.codepoints.to_a
=> [42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10]
irb(main):176:0> s=data[11933302..11933318]
=> "****************\n"
irb(main):177:0> s.valid_encoding?
=> false
irb(main):178:0> s.codepoints.to_a
=> [42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10]
但是一个较小的substr被认为是正确的编码

irb(main):179:0> s=data[11933308..11933318]
=> "**********\n"
irb(main):180:0> s.valid_encoding?
=> true
irb(main):181:0> s.codepoints.to_a
=> [42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10]
这看起来像是一个bug,其中原始数据可能有无效字符,但为什么没有任何无效字符的substr仍然作为无效编码出现,并且像
s.split(“\n”)
这样的操作会抛出错误,例如

irb(main):155:0> s.split(".")
ArgumentError: invalid byte sequence in UTF-8
    from (irb):155:in `split'
    from (irb):155
我在linux上使用ruby 1.9.1,语言环境设置为UTF-8,简而言之,
String\force\u编码(“UTF-8”)
可能就是您想要的?将其应用于字符串对象

从系统学的角度讲,我认为当原始字符串的字符代码无效时是公平的,它的任何子字符串的字符代码也将无效,因为您所做的切片在字符编码方面可能没有意义。例如,假设原始字符串的每个字符都有3个字节,并且如果从原始字符串的第2个字符中分割字符串,则生成的子字符串不应具有有效的编码,而是应将其视为纯字节数组。因此,当Ruby认为原始字符串的字符代码无效时,Ruby根据定义将不知道其子字符串中是否有有效的字符代码,除了空字符串

在这种情况下,我最感兴趣的是您的第三个示例,它给出了
s.valid\u编码?==正确
,而其他人则不正确

在最新的Ruby-2.1.4中,我认为由
String#[]
创建的子字符串基本上继承了原始字符串的编码和相关特征,然后可以根据条件重新定义编码

相应的功能是,,
rb\u str\u aref()
rb\u str\u substr()
rb\u enc\u cr\u str\u copy\u for\u substr()
→ 源代码中的
string.c
中的
str\u enc\u copy()。也,
ENCODING\u GET()
include/ruby/ENCODING.h
调用/使用
encoding.c
中的
rb\u enc\u get\u index()

但是,我没有发现任何迹象表明不同的子字符串可能最终具有不同的状态,即
String#valid\u encoding?


问题是,您正在使用的Ruby 1.9.1是一个相当古老的开发轨道,在我模糊的记忆中,这是相当有缺陷的,尽管Ruby 1.9和2.0的规范没有太大不同。这也许可以解释?

你知道你的文件应该用什么编码吗?它是UTF-8,我关心的不是找到字符,而是看看为什么子字符串仍然有无效的编码,但它的字节都没有错