6

使用 Ruby 1.9.2,我在 IRB 中有以下 Ruby 代码:

> r1 = /^(?=.*[\d])(?=.*[\W]).{8,20}$/i
> r2 = /^(?=.*\d)(?=.*\W).{8,20}$/i
> a = ["password", "1password", "password1", "pass1word", "password 1"]
> a.each {|p| puts "r1: #{r1.match(p) ? "+" : "-"} \"#{p}\"".ljust(25) + "r2: #{r2.match(p) ? "+" : "-"} \"#{p}\""}

这将产生以下输出:

r1: - "password"         r2: - "password"
r1: + "1password"        r2: - "1password"
r1: + "password1"        r2: - "password1"
r1: + "pass1word"        r2: - "pass1word"
r1: + "password 1"       r2: + "password 1"

1.) 为什么结果不同?

2.) 为什么会r1在字符串 2、3 和 4 上匹配?(?=.*[\W])由于这些示例中没有任何非单词字符,因此前瞻性不会导致它失败吗?

4

1 回答 1

6

这是由于几个正则表达式功能和 Unicode 之间的交互作用造成的。\W都是非单词字符,其中包括212A - “KELVIN SIGN” (PDF 链接)017F - “LATIN SMALL LETTER LONG S” ſ(PDF 链接)。添加了这两者的/i小写版本,即“普通”ks字符(006B - “LATIN SMALL LETTER K”和 0073 “LATIN SMALL LETTER S”(PDF 链接))。

因此,在某些情况下, sinpassword被解释为非单词字符。

请注意,这似乎仅\W在 位于字符类(即[\W])中时发生。此外,我只能在irb独立脚本中重现它,它似乎按预期工作。

有关更多信息,请参阅Ruby 错误

于 2012-11-26T22:14:51.697 回答