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-「KELVINSIGN (PDFリンク)および017F-「LATIN SMALL LETTER LONGS」ſ(PDFリンク)が含まれます。は/i、これらの両方の小文字バージョンを追加します。これは、「通常」ks文字です(006B-「LATINSMALLLETTERK」および0073「LATINSMALLLETTER S」(PDFリンク))。

したがって、特定の場合に単語以外の文字として解釈されているのsはそのためです。password

\Wこれは、が文字クラス(つまり)にある場合にのみ発生するように見えることに注意してください[\W]。また、これはでしか再現できませんirb。スタンドアロンスクリプト内では、期待どおりに機能しているようです。

詳細については、これに関するRubyのバグを参照してください。

于 2012-11-26T22:14:51.697 に答える