这个正则表达式:
regex1 = /\z/
以下字符串匹配:
"hello" =~ regex1 # => 5
"こんにちは" =~ regex1 # => 5
但是有了这些正则表达式:
regex2 = /#$/?\z/
regex3 = /\n?\z/
他们表现出差异:
"hello" =~ regex2 # => 5
"hello" =~ regex3 # => 5
"こんにちは" =~ regex2 # => nil
"こんにちは" =~ regex3 # => nil
什么是干扰?字符串编码是UTF-8,操作系统是Linux(即$/
是"\n"
)。多字节字符是否会干扰$/
?怎么样?
答案 0 :(得分:3)
您报告的问题绝对是Regexp
RUBY_VERSION #=> "2.0.0"
的错误,但在编码允许多字节字符(例如__ENCODING__ #=> #<Encoding:UTF-8>
不依赖于Linux,也可以在OSX和Windows中重现相同的行为。
在修复bug 8210的同时,我们可以通过隔离和了解发生问题的案例来提供帮助。 当适用于特定情况时,这对任何解决方法也很有用。
我知道问题发生在:
\z
之前搜索内容。?
该错误可能是由于字节数与正则表达式引擎实际检查的字符数之间的误解造成的。
一些例子可能有所帮助:
s = "んにちは"
s =~ /ん?\z/u #=> 4" # OK it works 3 == 3
s =~ /ç?\z/u #=> nil # KO: BUG when 3 > 2
s =~ /x?ç?\z/u #=> 4 # OK it works 3 == ( 1+2 )
s =~ /\n?\z/u #=> nil" # KO: BUG when 3 > 1
s =~ /\n?\n?\z/u #=> nil" # KO: BUG when 3 > 2
s =~ /\n?\n?\n?\z/u #=> 4" # OK it works 3 == ( 1+1+1)
通过TEST1的结果,我们可以断言:如果字符串的最后一个多字节字符是3个字节,那么“零或一个之前”测试仅在我们测试至少3个字节(而不是3个字节)时起作用字符)之前。
s = "in French there is the ç"
s =~ /ん?\z/u #=> 24 # OK 2 <= 3
s =~ /é?\z/u #=> 24 # OK 2 == 2
s =~ /x?é?\z/u #=> 24 # OK 2 < (2+1)
s =~ /\n?\z/u #=> nil # KO 2 > 1 ( the BUG occurs )
s =~ /\n?\n?\z/u #=> 24 # OK 2 == (1+1)
s =~ /\n?\n?\n?\z/u #=> 24 # OK 2 < (1+1+1)
根据TEST2的结果,我们可以断言:如果字符串的最后一个多字节字符是2个字节,那么“零或一个之前”测试仅在我们检查至少2个字节(不是2个字节)时起作用字符)之前。
当多字节字符不在字符串的末尾时,我发现它可以正常工作。
答案 1 :(得分:1)
在Ruby trunk中,此问题现在已被接受为错误。希望它会被修复。
更新:Ruby trunk中发布了两个补丁。