2013-10-03 5 views
5

Ich bin ziemlich neu in Regex, habe es gerade erst in der Schule gelernt. Ich habe meine erste Aufgabe und komme ziemlich gut durch.Validieren Sie die minimale/maximale Länge des Passworts

Lassen Sie mich erklären, so macht mein Code Sinn ... Die Aufgabe macht meine .NET Regex Tester durch einen Text für Passwörter suchen. Diese Passwörter können keine Leerzeichen enthalten (so habe ich \S) Kann nicht mit einer Zahl oder Unterstrichen beginnen, so habe ich (?m:^([^_|^0-9]{1}) kann nicht auf zwei verschiedenen Zeichen enden

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

mindestens eine enthalten Ziffer, also habe ich einen Lookahead verwendet. Jetzt ist die Sache hier, der Code ist eine ziemlich überladene Sache gerade jetzt.

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

Und ich muss noch eins hinzufügen, das Passwort muss zwischen 8 und 20 Zeichen lang sein. Ich weiß, ich muss {8,20} verwenden (denke ich), aber die Sache ist, egal, wo ich dies eingeben, es tötet vollständig die Suche.

Hat jemand eine Idee, wie ich das lösen kann?

Sehr geschätzt.

Antwort

1

[Disclaimer, das ist eine ziemlich lange Antwort!]

Ich werde mit der Zeichen-Grenze beginnen.

Sie werden (?<!\S) und (?!\S) zu verwenden, haben den Anfang und das Ende des Passworts, um anzuzeigen, und \S{8,20} für das eigentliche Passwort verwenden:

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

Wie Sie wahrscheinlich bereits wissen (?m) ist für mehrzeilige (^ und $ passt Anfang und Ende der Zeile anstelle der Zeichenfolge in diesem Modus).

(?<!\S) stellt sicher, dass es keine Nicht-Leerzeichen vor dem Passwort.

(?!\S) stellt sicher, dass es keine Nicht-Leerzeichen nach dem Passwort.

Nun fügen wir einige Einschränkungen:

Kann nicht mit der Nummer beginnen oder unterstreichen: (?![0-9_]) eine negative Vorschau zu Beginn des Passworts:

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

muss mindestens eine Ziffer enthalten: (?=\S+[0-9]) eine positive Vorschau am Anfang des Passworts:

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

Muss mit den gleichen Zeichen enden: Sie müssen den secon erfassen d bis zum letzten Zeichen und verwenden Sie eine Rückreferenz. Sie können den \S{8,20} Teil \S{6,18}(\S)\1 für diese Änderung:

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

das soll jetzt gut sein.


Um Ihre regex jetzt:

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

Erstens, die {1} überflüssig ist, denn wenn man es entfernen, wäre es gar nichts ändern.

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

Zweitens haben Sie unsymmetrische Klammern. Ich bin mir nicht sicher, was das sein sollte, aber ich denke, der erste Paren war nicht beabsichtigt.

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

Als nächstes wird die Zeichenklasse [^_|^0-9] jedes Zeichen außer _, |, ^ oder Bereich 0-9. Ich bin sicher, dass ein Passwort kann mit | oder ^ beginnen. Das Metazeichen | verliert in einer Zeichenklasse seine Bedeutung! Sie könnten dies nutzen: [^_0-9] statt und dies würde:

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

Es ist in Ordnung, dies zu verwenden, aber Sie werden im Auge behalten, dass dies das erste Zeichen im Passwort ist; Sie haben einen Bereich von 8 bis 20 Zeichen zu respektieren, und es hat nur geändert, um 7,19. Die einzige Sache, die damit bleibt, ist, dass es auch ein Leerzeichen akzeptiert.Sie können eine in der Zeichenklasse setzen, dies zu vermeiden:

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

Okay, besser sieht jetzt, nächste:

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

Zuerst ist eine benannter Capture-Gruppe, okay, mit einer Nicht-Capture-Gruppe mit der Groß-/Kleinschreibung-Unempfindlichkeits-Betriebsart an (nicht ganz notwendig, da wir in der Regex keine Alphabete haben) und \S{1} innerhalb dieser Nicht-Erfassungsgruppe. Auch hier ist die {1} redundant. Entfernen Sie es und die (?i) Modus wird daraus:

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

Das ist nicht so schlimm, wenn es die letzten zwei Zeichen übereinstimmt, wird es in der Tat arbeiten.

(?=.*\d) 

Funktioniert gut. Vielleicht möchten Sie nach anderen Zeichen als 0-9 suchen, die \d entspricht, aber wenn es Ihnen nichts ausmacht, funktioniert das fast; Es wäre besser, \S anstelle von . hier zu verwenden, nur für den Fall, dass zwei Passwörter durch ein Leerzeichen nebeneinander im Text getrennt sind und dies dazu führen könnte, dass die Dinge nicht wie gewünscht verlaufen.

(\S*) 

Dieser Teil ist mehr oder weniger in Ordnung. Es gibt keine Begrenzung.

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

Okay, erinnere mich jetzt, dass (?m:^[^_0-9]) ein Zeichen nahm und (?<finalTwo>\S)(?:\<finalTwo>) nimmt zwei Zeichen, für insgesamt 3. Die Grenze Sie ist somit verhängen:

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

Es ist fast funktioniert, und Sie Sie müssen nur etwas setzen, um die teilweise Übereinstimmung längerer Passwörter zu verhindern. Sie können normalerweise Wortgrenzen verwenden \b, aber nichts wurde über Symbole erwähnt, so ist es sicherer anzunehmen, dass ein Passwort wie [email protected]*&AUn++ auch zulässig ist und das ist, wo die Wortgrenzen fehlschlagen. Deshalb schlage ich die Verwendung der negativen Blickwinkel vor.

0

Wie über die folgenden:

^(?!^[^0-9]+$)[^0-9_].{5,17}(.)\1$ 

^: start-of-String.

(?!^[^0-9]+$): Stellen Sie sicher, dass eine Ziffer vorhanden ist, indem Sie sicherstellen, dass das Kennwort nicht nur aus einer Kombination von Zeichen ohne Ziffern besteht.

[^0-9_]: Stellen Sie sicher, dass es mit etwas beginnt, das keine Ziffer oder Unterstrich ist.

.{5,17}: Stellen Sie jedes Zeichen zwischen 5 und 17 Mal.

(.): Richten Sie die Zeichen kurz vor dem letzten, und erfassen sie in Gruppe 1.

\1: Stellen Sie sicher, dass das letzte Zeichen der gleiche wie der, bevor es ist.

$: Ende der Zeichenfolge.

[^0-9_], (.) und \1 aufzunehmen 3 Zeichen, verläßt dieses 5 Zeichen als Minimum für .{5,17} und damit die 5 als die minimale Grenze und somit 17 als die obere Grenze, die insgesamt maximal 20 Zeichen macht.

Regex101 Demo

Ich weiß, dass die Demo PHP verwendet, aber es ist nicht wirklich wichtig hier.

Verwandte Themen