在Ruby(2.4)中,我可以创建一个字符串,其编码为UTF-8但在UTF-8中包含一个无效的字节(让我们使用字节E1
)。
然后当我尝试将正则表达式与此字符串匹配时,我收到错误。
2.4.0 :001 > "Hi! \xE1".match?(//)
ArgumentError: invalid byte sequence in UTF-8
from (irb):1:in `match?'
from (irb):1
当我在Python 3中做同样的事情时,我没有收到错误。
>>> import re; re.match('', "Hi! \xE1")
<_sre.SRE_Match object; span=(0, 0), match=''>
我的理解是,在这两种情况下,我都处于犯罪状态,因为我正在创建包含UTF-8中无效字节的UTF-8编码字符串。鉴于:
答案 0 :(得分:0)
在Ruby中,使用引号(即'Hi!'
)创建新字符串将创建核心String类的实例。如您所述,在2.0或更高版本中,ruby默认将源文件中的字符串解释为UTF-8。如果然后在字符串实例上调用一个方法,它将使用配置的编码来解释构成字符串的字节并应用该方法(所以为了回答你的第一个问题,它不是特定于正则表达式匹配 - 你会看到如果您调用gsub
或split
或任何其他字符串方法,则会出现相同的错误。
作为this post有用的细节,python 3默认将字符串解释为Unicode;但是,当ruby默认为UTF-8时,python 3默认为UTF-16或UTF-32,具体取决于解释器的构建方式,因此\xE1
无效。
有趣的是,如果你给python一些不是unicode的十六进制,它似乎把它留作明文:
>>> '\uffff'
'\uffff'
如果你给它废话(非十六进制),它会引发一个错误:
>>> "Hi! \xz1"
File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 4-5: truncated \xXX escape