5

私は正規表現にかなり慣れていませんが、学校で学び始めたばかりです。私は最初の課題を受け取り、かなりうまくやり遂げています。

私のコードが理にかなっているように説明させてください... 割り当ては、.NET Regex Tester にパスワードのテキストを検索させることです。これらのパスワードには空白を含めることはできません (したがって、使用\Sしました) 数字またはアンダースコアで開始することは(?m:^([^_|^0-9]{1}) できません。したがって、2 つの異なる文字で終了することはできません

(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)

少なくとも 1 つの数字を含める必要があるため、先読みを使用しました。さて、ここでの問題は、コードが現在かなり雑然としていることです。

(?=.*\d)(?m:^([^_|^0-9]{1})(\S*)(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>))

もう 1 つ追加しなければならないのは、パスワードは 8 ~ 20 文字の長さでなければならないということです。使用しなければならないことはわかっていますが{8,20}(私はそう思います)、問題は、これをどこに入力しても、検索が完全に無効になることです。

どうすればこれを解決できるか考えている人はいますか?

とても有難い。

4

2 に答える 2

1

[免責事項、それはかなり長い答えです!]

文字数制限から始めます。

(?<!\S)およびを使用し(?!\S)て、パスワードの最初と最後を示し、\S{8,20}実際のパスワードに使用する必要があります。

(?m)(?<!\S)\S{8,20}(?!\S)

おそらくすでにご存知のよう(?m)に、複数行用です(^and$は、このモードの文字列ではなく、行頭と行末にそれぞれ一致します)。

(?<!\S)パスワードの前に空白以外の文字がないことを確認してください。

(?!\S)パスワードの後に​​空白以外の文字がないことを確認してください。

次に、いくつかの制限を追加します。

数字またはアンダースコアで始めることはできません:(?![0-9_])パスワードの先頭に否定的な先読みがあります:

(?m)(?<!\S)(?![0-9_])\S{8,20}(?!\S)

少なくとも 1 つの数字が含まれている必要が(?=\S+[0-9])あります: パスワードの先頭に肯定的な先読み:

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{8,20}(?!\S)

同じ文字で終わる必要があります: 最後から 2 番目の文字をキャプチャし、後方参照を使用する必要があります。\S{8,20}このためにパーツを次のように変更できます\S{6,18}(\S)\1

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{6,18}(\S)\1(?!\S)

これでいいはずです。


今すぐ正規表現に:

(?m:^([^_|^0-9]{1})

まず、{1} を削除しても何も変わらないため、{1} は冗長です。

(?m:^([^_|^0-9])

第二に、括弧のバランスが取れていません。それがどうあるべきかはわかりませんが、最初の親は意図されていなかったと思います。

(?m:^[^_|^0-9])

次に、文字クラスは、、、または範囲を[^_|^0-9]除く任意の文字に一致します。パスワードは、またはで始まることができると確信しています。メタキャラクターは、文字クラスでその意味を失います! これを使用できます:代わりに、これは次のようになります。_|^0-9|^|[^_0-9]

(?m:^[^_0-9])

これを使用してもかまいませんが、これがパスワードの最初の文字であることを覚えておく必要があります。8 から 20 文字の範囲があり、それが 7,19 に変更されました。残っている唯一のことは、スペースも受け入れることです。これを避けるために、文字クラスに1つ入れることができます:

(?m:^[^_0-9 ])

よし、良くなったね。次は。

(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)

1 つ目は名前付きのキャプチャ グループです。大文字と小文字を区別しないモードがオンになっている非キャプチャ グループ (正規表現にアルファベットがないため、それほど必要ではありません) と\S{1}その非キャプチャ グループ内にあります。繰り返しますが、{1}は冗長です。(?i)それとモードを削除すると、次のようになります。

(?<finalTwo>\S)(?:\<finalTwo>)

それはそれほど悪くはありません。最後の 2 文字に一致する場合は、実際に機能します。

(?=.*\d)

うまくいきます。0-9一致するもの以外の文字を探したいと思うかもしれませんが\d、気にしなければほとんどうまくいきます。テキスト内にスペースで区切られた 2 つのパスワードがあり、意図したとおりに動作しない可能性がある場合に備えて、ここ\Sの代わりに使用することをお勧めします。.

(\S*)

その部分はほぼ大丈夫です。課された制限はありません。

(?=\S*\d)(?m:^[^_0-9 ])(\S*)(?<finalTwo>\S)(?:\<finalTwo>)

(?m:^[^_0-9])さて、ここで1 文字と(?<finalTwo>\S)(?:\<finalTwo>)2 文字で、合計 3 文字であることを思い出してください。このようにして課す制限は次のとおりです。

(?=\S*\d)(?m:^[^_0-9 ])(\S{5,17})(?<finalTwo>\S)(?:\<finalTwo>)

それはほとんど機能し、長いパスワードの部分的な一致を防ぐために何かを配置するだけで済みます. 通常は単語境界を使用できますが、\b記号については何も言及されていないため、次のようなパスワード$@4*&AUn++も許可されており、単語境界が失敗する場所であると想定する方が安全です。そのため、否定的なルックアラウンドの使用をお勧めします。

于 2013-10-03T16:40:57.857 に答える