【问题标题】:Why am I seeing different results for these two nearly identical Ruby regex patterns, and why is one matching what I think it shouldn't?为什么我看到这两个几乎相同的 Ruby 正则表达式模式的结果不同,为什么一个匹配我认为它不应该匹配的结果?
【发布时间】:2012-11-14 10:03:21
【问题描述】:

使用 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]) 前瞻不会导致它失败,因为这些示例中没有任何非单词字符?

【问题讨论】:

  • 您能否尝试匹配/^(?=.*[\d])(?=.*([\W])).{8,20}$/i 并告诉使用捕获组1 中捕获的内容? (恐怕是数字,但你永远不知道)
  • 使用 Ruby 1.9.3-p327 的结果: r1: - "password" r2: - "password" r1: - "1password" r2: - "1password" r1: - "password1" r2: - "password1" r1: - "pass1word" r2: - "pass1word" r1: + "password 1" r2: + "password 1" => ["password", "1password", "password1", "pass1word", "password 1"] 看起来您可能发现了 1.9.2 的错误?
  • 能否在您的问题中包含该问题(为了格式正确)
  • @ilanberci,我仍然在 1.9.3-p327 中看到相同的确切结果。 gist.github.com/a839ed2b3efdc949b894

标签: ruby regex unicode character-class


【解决方案1】:

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

所以在某些情况下,password 中的 s 被解释为非单词字符。

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

请参阅the Ruby bug about this 了解更多信息。

【讨论】:

  • 好收获。没关系,但actual problem 不是ß(折叠成ss),而是017F - LATIN SMALL LETTER LONG S ſ(折叠成单个s)。跨度>
  • @Pumbaa80 谢谢,这更有意义,我已经更新了答案。我从a different comment on the bug report 中获取了ß。在这种情况下,ß 也会匹配,因为 password 中的双 s,但实际匹配的是单 s,所以它可能是 ſ
  • 哇,这是一个有趣的功能 :) 感谢您的解释和错误报告的链接。
  • 由于我的正则表达式最终不需要区分大小写,只需关闭该标志就会导致预期的行为。
猜你喜欢
  • 1970-01-01
  • 2015-08-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 2018-08-24
  • 2022-11-30
  • 2015-06-27
  • 2018-06-02
相关资源
最近更新 更多