Ich erstelle einen regulären Ausdruck für die Kennwortüberprüfung, um in einer Java-Anwendung als Konfigurationsparameter verwendet zu werden.
Der reguläre Ausdruck ist:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
Die Passwortrichtlinie lautet:
Mindestens 8 Zeichen
Enthält mindestens eine Ziffer
Enthält mindestens ein unteres Zeichen und ein oberes Zeichen
Enthält mindestens ein Zeichen innerhalb einer Reihe von Sonderzeichen (@#%$^
usw.)
Enthält keine Leerzeichen, Tabulatoren usw.
Ich vermisse nur Punkt 5. Ich kann den Regex-Ausdruck nicht auf Platz, Registerkarte, Wagenrücklauf usw. überprüfen lassen.
Könnte mir jemand helfen?
Versuche dies:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
Erläuterung:
^ # start-of-string
(?=.*[0-9]) # a digit must occur at least once
(?=.*[a-z]) # a lower case letter must occur at least once
(?=.*[A-Z]) # an upper case letter must occur at least once
(?=.*[@#$%^&+=]) # a special character must occur at least once
(?=\S+$) # no whitespace allowed in the entire string
.{8,} # anything, at least eight places though
$ # end-of-string
Es ist leicht, einzelne Regeln hinzuzufügen, zu ändern oder zu entfernen, da jede Regel ein unabhängiges "Modul" ist.
Das (?=.*[xyz])
-Konstrukt frisst die gesamte Zeichenfolge (.*
) und führt zum ersten Vorkommen zurück, bei dem [xyz]
übereinstimmen kann. Wenn [xyz]
gefunden wird, schlägt dies fehl, andernfalls schlägt es fehl.
Die Alternative wäre die Verwendung eines widerstrebenden Qualifizierers: (?=.*?[xyz])
. Bei einer Passwortüberprüfung macht das kaum einen Unterschied, bei längeren Zeichenketten kann es die effizientere Variante sein.
Die effizienteste Variante (aber am schwierigsten zu lesen und zu warten, daher die fehleranfälligste) wäre natürlich (?=[^xyz]*[xyz])
. Für einen Regex dieser Länge und zu diesem Zweck würde ich es nicht empfehlen, es so zu machen, da es keinen wirklichen Nutzen hat.
einfaches Beispiel mit Regex
public class passwordvalidation {
public static void main(String[] args) {
String passwd = "[email protected]";
String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
System.out.println(passwd.matches(pattern));
}
}
Erklärungen:
(?=.*[0-9])
eine Ziffer muss mindestens einmal vorkommen(?=.*[a-z])
ein Kleinbuchstabe muss mindestens einmal vorkommen(?=.*[A-Z])
Ein Großbuchstabe muss mindestens einmal vorkommen(?=.*[@#$%^&+=])
ein Sonderzeichen muss mindestens einmal vorkommen(?=\\S+$)
In der gesamten Zeichenfolge ist kein Leerzeichen zulässig.{8,}
mindestens 8 ZeichenAlle zuvor gegebenen Antworten verwenden dieselbe (richtige) Technik, um für jede Anforderung einen separaten Lookahead zu verwenden. Sie enthalten jedoch einige Ineffizienzen und einen potenziell massiven Fehler, je nachdem, welches Back-End das Passwort tatsächlich verwendet.
Ich fange mit der Regex von der akzeptierten Antwort an:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$
Da Java \A
und \z
unterstützt, ziehe ich es vor, diese zu verwenden, um sicherzustellen, dass die gesamte Zeichenfolge unabhängig von Pattern.MULTILINE
überprüft wird. Dies wirkt sich nicht auf die Leistung aus, vermeidet jedoch Fehler beim Recycling von Regex.
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z
Die Überprüfung, dass das Kennwort kein Leerzeichen enthält, und die Überprüfung der Mindestlänge kann in einem einzigen Durchgang durchgeführt werden. Verwenden Sie all all auf einmal, indem Sie den Variablenquantifizierer {8,}
in das Kürzel \S
setzen, das die zulässigen Zeichen begrenzt:
\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z
Wenn das bereitgestellte Kennwort ein Leerzeichen enthält, werden alle Überprüfungen durchgeführt, nur damit die letzte Überprüfung des Leerzeichens fehlschlägt. Dies kann vermieden werden, indem alle Punkte durch \S
ersetzt werden:
\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z
Der Punkt sollte nur verwendet werden, wenn Sie wirklich ein Zeichen zulassen möchten. Verwenden Sie andernfalls eine (negierte) Zeichenklasse, um Ihre Regex auf nur die Zeichen zu beschränken, die wirklich zulässig sind. In diesem Fall macht es wenig aus, den Punkt nicht zu verwenden, wenn etwas anderes angemessener ist ist eine sehr gute Angewohnheit. Ich sehe viel zu viele Fälle von katastrophales Backtracking , weil der Entwickler zu faul war, etwas passenderes als den Punkt zu verwenden.
Da es gute Chancen gibt, dass die ersten Tests in der ersten Hälfte des Passworts ein passendes Zeichen finden, kann ein Lazer-Quantifier effizienter sein:
\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z
Nun aber zu dem wirklich wichtigen Thema: In keiner der Antworten wird die Tatsache erwähnt, dass die ursprüngliche Frage von jemandem geschrieben wurde, der in ASCII denkt. In Java sind Strings jedoch Unicode. Sind nicht-ASCII-Zeichen in Kennwörtern zulässig? Wenn dies der Fall ist, sind nur Leerzeichen ASCII unzulässig oder sollten alle Unicode-Leerzeichen ausgeschlossen werden.
Standardmäßig entspricht \s
nur ASCII Whitespace, daher entspricht der inverse \S
allen Unicode-Zeichen (Whitespace oder nicht) und allen Nicht-Whitespace-Zeichen ASCII. Wenn Unicode-Zeichen zulässig sind, Unicode-Leerzeichen jedoch nicht, kann das Flag UNICODE_CHARACTER_CLASS
angegeben werden, um \S
Unicode-Whitespace auszuschließen. Wenn Unicode-Zeichen nicht zulässig sind, kann [\x21-\x7E]
anstelle von \S
verwendet werden, um alle ASCII - Zeichen abzugleichen, die kein Leerzeichen oder Steuerzeichen sind.
Das bringt uns zur nächsten möglichen Frage: Wollen wir Steuerzeichen zulassen? Der erste Schritt beim Schreiben einer richtigen Regex ist, genau anzugeben, was Sie anpassen möchten und was nicht. Die einzige zu 100% technisch korrekte Antwort ist, dass die Kennwortangabe in der Frage mehrdeutig ist, da nicht angegeben wird, ob bestimmte Zeichenbereiche wie Steuerzeichen oder Nicht-ASCII-Zeichen zulässig sind oder nicht.
Sie sollten nicht zu komplexes Regex verwenden (wenn Sie sie vermeiden können), da dies der Fall ist
Obwohl bei der Verwendung vieler kleiner regulärer Ausdrücke ein geringer Performance-Aufwand anfallen kann, sind die Punkte übergewichtig.
Ich würde so umsetzen:
bool matchesPolicy(pwd) {
if (pwd.length < 8) return false;
if (not pwd =~ /[0-9]/) return false;
if (not pwd =~ /[a-z]/) return false;
if (not pwd =~ /[A-Z]/) return false;
if (not pwd =~ /[%@$^]/) return false;
if (pwd =~ /\s/) return false;
return true;
}
Passwortanforderung:
Kennwörter müssen Zeichen aus mindestens zwei (2) dieser Gruppierungen enthalten: alpha-, numerische und Sonderzeichen.
^.*(?=.{8,})(?=.*\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\d)(?=.*[[email protected]#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[[email protected]#$%^&]).*$
Ich habe es getestet und es funktioniert
Für jeden, der an Mindestanforderungen für jeden Charaktertyp interessiert ist, würde ich vorschlagen, die folgende Erweiterung über die akzeptierte Antwort von Tomalak vorzunehmen:
^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$
Beachten Sie, dass dies eine Formatierungszeichenfolge ist und nicht das endgültige Regex-Muster. Ersetzen Sie einfach% d durch die minimal erforderlichen Vorkommen für: Ziffern, Kleinbuchstaben, Großbuchstaben, Nicht-Ziffern/-Zeichen und das gesamte Kennwort (jeweils). Maximales Vorkommen ist unwahrscheinlich (es sei denn, Sie möchten eine maximale Anzahl von 0 haben und solche Zeichen effektiv ablehnen), diese könnten jedoch problemlos hinzugefügt werden. Beachten Sie die zusätzliche Gruppierung um jeden Typ, sodass die Min/Max-Einschränkungen nicht aufeinander folgende Übereinstimmungen zulassen. Dies war ein Wunder für ein System, in dem wir zentral konfigurieren konnten, wie viele Zeichen jeder Charaktertyp wir brauchten, und die Website sowie zwei verschiedene mobile Plattformen diese Informationen abrufen konnten, um das Regex-Muster auf der Grundlage der obigen Formatierungszeichenfolge zu erstellen.
String s=pwd;
int n=0;
for(int i=0;i<s.length();i++)
{
if((Character.isDigit(s.charAt(i))))
{
n=5;
break;
}
else
{
}
}
for(int i=0;i<s.length();i++)
{
if((Character.isLetter(s.charAt(i))))
{
n+=5;
break;
}
else
{
}
}
if(n==10)
{
out.print("Password format correct <b>Accepted</b><br>");
}
else
{
out.print("Password must be alphanumeric <b>Declined</b><br>");
}
Erklärung:
Ich denke, das kann es auch (als einfacherer Modus):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$
Java-Methode für Sie bereit, mit Parametern
Einfach kopieren und einfügen und die gewünschten Parameter einstellen.
Wenn Sie kein Modul wünschen, kommentieren Sie es einfach oder fügen Sie ein "wenn" für ein spezielles Zeichen hinzu
//______________________________________________________________________________
/**
* Validation Password */
//______________________________________________________________________________
private static boolean validation_Password(final String PASSWORD_Arg) {
boolean result = false;
try {
if (PASSWORD_Arg!=null) {
//_________________________
//Parameteres
final String MIN_LENGHT="8";
final String MAX_LENGHT="20";
final boolean SPECIAL_CHAR_NEEDED=true;
//_________________________
//Modules
final String ONE_DIGIT = "(?=.*[0-9])"; //(?=.*[0-9]) a digit must occur at least once
final String LOWER_CASE = "(?=.*[a-z])"; //(?=.*[a-z]) a lower case letter must occur at least once
final String UPPER_CASE = "(?=.*[A-Z])"; //(?=.*[A-Z]) an upper case letter must occur at least once
final String NO_SPACE = "(?=\\S+$)"; //(?=\\S+$) no whitespace allowed in the entire string
//final String MIN_CHAR = ".{" + MIN_LENGHT + ",}"; //.{8,} at least 8 characters
final String MIN_MAX_CHAR = ".{" + MIN_LENGHT + "," + MAX_LENGHT + "}"; //.{5,10} represents minimum of 5 characters and maximum of 10 characters
final String SPECIAL_CHAR;
if (SPECIAL_CHAR_NEEDED==true) SPECIAL_CHAR= "(?=.*[@#$%^&+=])"; //(?=.*[@#$%^&+=]) a special character must occur at least once
else SPECIAL_CHAR="";
//_________________________
//Pattern
//String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
final String PATTERN = ONE_DIGIT + LOWER_CASE + UPPER_CASE + SPECIAL_CHAR + NO_SPACE + MIN_MAX_CHAR;
//_________________________
result = PASSWORD_Arg.matches(PATTERN);
//_________________________
}
} catch (Exception ex) {
result=false;
}
return result;
}
Auch das können Sie tun.
public boolean isPasswordValid(String password) {
String regExpn =
"^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$";
CharSequence inputStr = password;
Pattern pattern = Pattern.compile(regExpn,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
return true;
else
return false;
}
einfaches
("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")
(?! irgendwas) -> (umgekehrt) bedeutet negative Vorwärtsschau, wenn Bedingung geschrieben return false ist.
schließen Bedeutung ^ (Bedingung) (Bedingung) (Bedingung) (Bedingung) [\ S] {8,10} $
Dieser prüft für jedes Sonderzeichen:
^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\S+$).*[A-Za-z0-9].{8,}$