3

私はこの正規表現に出くわしましたが、これがどのように使用されているのか疑問に思っていました:

^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$

正規表現全体が何をするかだけでなく、正規表現の個々のセクションが何を意味するのかを知りたいです。

私が持っている正規表現の知識では、数字(0-9)、小文字、大文字に一致する任意の入力(少なくとも10文字の長さ)に一致すると思いますが、これが正しいかどうか確認が必要ですか?

編集

また、検証する意味もわかりませんが、それが何をしていると思うかを見ると、正規表現を次のように単純化できるのは正しいですか。

[\d|[a-zA-Z]]{10,}

編集 2 交換用の正規表現では、すべての要件 (少なくとも数字、大文字、小文字) の少なくとも 1 つが確実に満たされていないように気付きました。正規表現がそれを行うように調整する方法はありますか、それとも元の正規表現でのみ可能ですか?

4

4 に答える 4

6

正規表現の部分が何をするのか説明できますが、一般的にこれは非常に奇妙だと思います:

^.*(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$

基本的にあなたが言ったことは本当です-正規表現には他の魔法はありません。

^.*- 行頭と 0+ 文字を一致させてから、

以下は主張するだけです-それらのどれも何にも一致/キャプチャしません。調べたい場合は、前向き先読みと呼ばれます。それらのすべてが true と評価された場合、正規表現の最後の部分が残りを行います。

(?=.{10,})- 最初の一致が停止する場所 (行頭の後である可能性があります) から、10 文字以上の文字列 (任意の文字) があります。

(?=.*\d)- そして、文字列全体の前に少なくとも 1 つの数字がある

(?=.*[a-z])- および小文字

(?=.*[A-Z])- と大文字

それがすべて正しい場合、次のようになります。

.*$- 行末まですべて一致

注: アサーションのいずれかが失敗した場合、何も一致しません。

あなたの編集に

私はそうは思いません-文字列のどこかに大文字と小文字と数字があると言うのと、文字列が10以上の文字で構成されており、そのすべてが数字か文字であると言うのは同じではありません(大文字または小文字) またはその両方。正規表現は、数字のみと文字のみ、または両方の組み合わせで構成される文字列に一致します。元の正規表現は、これらのクラスのそれぞれが少なくとも 1 回表現されることを保証します。誰かがそれを使用して、ユーザーのパスワードなどを検証した可能性があります。

于 2012-05-31T07:26:07.903 に答える
1

これはパスワードの強度を確保するために使用されていると思います。少なくとも 10 文字の長さで、少なくとも 1 つの数字、少なくとも 1 つの小文字、少なくとも 1 つの大文字が必要です。

正規表現全体の中で最も重要な部分は(?=...)演算子です。これは一致しますが、一致する文字列の一部を消費しません。(?=...)したがって、隣り合う複数は AND 演算子として機能します。

(?=.{10,})10 文字以上の任意のシーケンスに一致します。

(?=.*\d)任意の後に続く 1 桁の数字に一致します。

(?=.*[a-z])任意の後に続く小文字の char に一致します。

(?=.*[A-Z])任意の後に続く大文字に一致します。

したがって、この正規表現は、少なくとも 10 文字の長さで、少なくとも 1 つの数字、小文字の文字、および大文字の文字を含む部分文字列を持つ任意の文字列と一致します。

特に部分文字列部分が、必要以上に複雑に聞こえることがわかります。確かに、.*直後の部分^は不要であり、これを次のように単純化できます。

^(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$
于 2012-05-31T07:42:11.477 に答える
1

これはおそらく、候補パスワードを検証するために使用されます。

  1. 長さが 10 文字以上であることを確認します
  2. 少なくとも 1 つの数字が含まれていることを確認します
  3. 少なくとも 1 つの小文字が含まれていることを確認します
  4. 少なくとも 1 つの大文字が含まれていることを確認します

上記の条件をORするだけなので、置換正規表現は同一ではありません-長い厄介な正規表現はそれらをANDします。また、上記の条件に順序はありません。文字または数字は、文字列のどこにでも出現できます。

実際にはこれ以上単純化する方法はありません。最初の .* と最後の .*$ は実際には何の役にも立たないため、削除することもできます。しかし、それ以外の場合、その長い正規表現は、順序を課すことなく、それらの条件を連言的に課すのに適しています。

于 2012-05-31T07:27:46.903 に答える
0

他の人が言ったように、これはパスワード強度検証の正規表現ですが.*、最初はそこにあるべきではありません。そのままでは、 は.*最初に文字列全体を消費し、次に 4 つの先読みすべてが一致する位置に到達するまでバックトラックします。それは機能しますが、必要がないのに、なぜ正規表現をそれほど機能させるのでしょうか?

^(?=.{10,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$

先頭を.*削除すると、正規表現はバックトラックする必要がありません(先読みバックトラックが成功した後に開始位置に戻ることを数えない限り)。最後にについては.*$、必要ないかもしれませんが、害はありません。誰かが元の文字列の代わりに一致の結果を何かに使用しようとした場合に備えて、そのままにしておきます。

もう 1 つのポイント: 最初の先読みを削除し.{10,}、代わりに を配置することで、正規表現をより簡潔にすることができ.*ます。

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,}$

このように記述されている理由は、Internet Explorer の長年のバグ ( ref ) を回避するためです。バグは最終的に IE8 または IE9 で修正されましたが、念のためそのままにしておきます。

于 2012-05-31T08:56:17.763 に答える