Tworzę wyrażenie regularne do weryfikacji hasła, które ma być używane w aplikacji Java jako parametr konfiguracyjny.
Wyrażenie regularne to:
^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$
Polityka haseł to:
Co najmniej 8 znaków
Zawiera co najmniej jedną cyfrę
Zawiera co najmniej jeden dolny znak alfa i jeden górny znak alfa
Zawiera co najmniej jeden znak w zestawie znaków specjalnych (
@#%$^
itp.)Nie zawiera spacji, tabulacji itp.
Brakuje mi tylko punktu 5. Nie mogę sprawdzić wyrażenia regularnego pod kątem spacji, tabulacji, powrotu karetki itp.
Czy ktoś mógłby mi pomóc?
Odpowiedzi:
Spróbuj tego:
Wyjaśnienie:
Łatwo jest dodawać, modyfikować lub usuwać poszczególne reguły, ponieważ każda reguła jest niezależnym „modułem”.
(?=.*[xyz])
Konstrukt zjada cały ciąg (.*
) i cofa się do pierwszego wystąpienia, gdzie[xyz]
może się równać. Uda się, jeśli[xyz]
zostanie znaleziony, w przeciwnym razie zakończy się niepowodzeniem.Alternatywą byłoby użycie niechętnego kwalifikatora:
(?=.*?[xyz])
. W przypadku sprawdzania hasła nie będzie to miało większego znaczenia, w przypadku znacznie dłuższych ciągów może to być bardziej wydajny wariant.Najbardziej wydajnym wariantem (ale najtrudniejszym do odczytania i utrzymania, a zatem najbardziej podatnym na błędy) byłby
(?=[^xyz]*[xyz])
oczywiście. W przypadku wyrażenia regularnego o tej długości i w tym celu odradzałbym robienie tego w ten sposób, ponieważ nie daje to żadnych rzeczywistych korzyści.źródło
\\s
. To jest wymóg Javy, a nie wymóg wyrażenia regularnego.(?=...)
wzorzec, aby pasował do konfiguracji reszty wyrażenia ..(?=\S+$)
), czy „nie zawiera znaków spacji” ((?!.*\s)
), jest kwestią preferencji. Użyj tego, co lubisz lepiej. :)prosty przykład z użyciem wyrażenia regularnego
Objaśnienia:
(?=.*[0-9])
cyfra musi wystąpić co najmniej raz(?=.*[a-z])
mała litera musi wystąpić przynajmniej raz(?=.*[A-Z])
wielka litera musi wystąpić przynajmniej raz(?=.*[@#$%^&+=])
znak specjalny musi wystąpić przynajmniej raz(?=\\S+$)
w całym ciągu znaków nie można używać białych znaków.{8,}
co najmniej 8 znakówźródło
Wszystkie udzielone wcześniej odpowiedzi wykorzystują tę samą (poprawną) technikę, aby użyć osobnego wyprzedzenia dla każdego wymagania. Ale zawierają kilka nieefektywności i potencjalnie ogromny błąd, w zależności od zaplecza, które faktycznie będzie używać hasła.
Zacznę od wyrażenia regularnego z zaakceptowanej odpowiedzi:
Przede wszystkim, ponieważ Java obsługuje
\A
i\z
wolę ich używać, aby upewnić się, że cały ciąg jest zweryfikowany, niezależnie odPattern.MULTILINE
. Nie wpływa to na wydajność, ale pozwala uniknąć błędów podczas odtwarzania wyrażeń regularnych.Sprawdzenie, czy hasło nie zawiera białych znaków i sprawdzenie jego minimalnej długości, można wykonać w jednym przebiegu, używając funkcji all na raz, umieszczając zmienny kwantyfikator
{8,}
w skrócie,\S
który ogranicza dozwolone znaki:Jeśli podane hasło zawiera spację, wszystkie sprawdzenia zostaną wykonane, tylko po to, aby ostatnie sprawdzenie miejsca zakończyło się niepowodzeniem. Można tego uniknąć, zastępując wszystkie kropki
\S
:Kropki należy używać tylko wtedy, gdy naprawdę chcesz dopuścić dowolny znak. W przeciwnym razie użyj (zanegowanej) klasy znaków, aby ograniczyć swoje wyrażenie regularne tylko do tych znaków, które są naprawdę dozwolone. Chociaż w tym przypadku nie ma to większego znaczenia, nieużywanie kropki, gdy coś innego jest bardziej odpowiednie, jest bardzo dobrym nawykiem. Widzę zbyt wiele przypadków katastrofalnego cofania się, ponieważ programista był zbyt leniwy, aby użyć czegoś bardziej odpowiedniego niż kropka.
Ponieważ istnieje duża szansa, że początkowe testy znajdą odpowiedni znak w pierwszej połowie hasła, leniwy kwantyfikator może być bardziej wydajny:
Ale teraz przejdźmy do naprawdę ważnej kwestii: żadna z odpowiedzi nie wspomina o tym, że pierwotne pytanie wydaje się być napisane przez kogoś, kto myśli w ASCII. Ale w Javie ciągi znaków to Unicode. Czy w hasłach dozwolone są znaki spoza zestawu ASCII? Jeśli tak, są dozwolone tylko spacje ASCII lub należy wykluczyć wszystkie białe spacje Unicode.
Domyślnie
\s
dopasowuje tylko białe znaki ASCII, więc jego odwrotność\S
dopasowuje wszystkie znaki Unicode (białe lub nie) i wszystkie znaki ASCII niebędące białymi znakami. Jeśli znaki Unicode są dozwolone, ale spacje Unicode nie są,UNICODE_CHARACTER_CLASS
można określić flagę, aby\S
wykluczyć białe znaki Unicode. Jeśli znaki Unicode nie są dozwolone,[\x21-\x7E]
można ich użyć zamiast\S
znaku ASCII, które nie są spacjami ani znakami sterującymi.Co prowadzi nas do następnego potencjalnego problemu: czy chcemy pozwolić postaciom sterującym? Pierwszym krokiem w tworzeniu odpowiedniego wyrażenia regularnego jest dokładne określenie, co chcesz dopasować, a czego nie. Jedyną w 100% poprawną technicznie odpowiedzią jest to, że specyfikacja hasła w pytaniu jest niejednoznaczna, ponieważ nie określa, czy niektóre zakresy znaków, takie jak znaki sterujące lub znaki spoza zestawu ASCII, są dozwolone, czy nie.
źródło
Nie powinieneś używać zbyt złożonych Regexów (jeśli możesz ich uniknąć), ponieważ tak jest
Chociaż użycie wielu małych wyrażeń regularnych może wiązać się z niewielkim narzutem wydajności, powyższe punkty łatwo go przeważają.
Wdrożyłbym w ten sposób:
źródło
Wymagane hasło:
Hasła muszą zawierać znaki z co najmniej dwóch (2) z tych grup: znaki alfanumeryczne i specjalne.
Przetestowałem to i działa
źródło
Wszystkim zainteresowanym minimalnymi wymaganiami dla każdego typu postaci proponuję następujące rozszerzenie w stosunku do zaakceptowanej odpowiedzi Tomalaka:
Zwróć uwagę, że jest to ciąg formatujący, a nie ostateczny wzorzec wyrażenia regularnego. Po prostu zastąp% d minimalną wymaganą liczbą wystąpień: cyfry, małe litery, wielkie litery, niecyfry / znaki i całe hasło (odpowiednio). Maksymalna liczba wystąpień jest mało prawdopodobna (chyba że chcesz mieć maksymalnie 0, skutecznie odrzucając takie znaki), ale można je również łatwo dodać. Zwróć uwagę na dodatkowe grupowanie wokół każdego typu, aby ograniczenia min / max zezwalały na niekolejne dopasowania. Zdziałało to cuda w systemie, w którym mogliśmy centralnie skonfigurować liczbę znaków każdego typu, których potrzebowaliśmy, a następnie mieć witrynę internetową oraz dwie różne platformy mobilne, aby pobrać te informacje w celu skonstruowania wzorca wyrażenia regularnego w oparciu o powyższy ciąg formatujący.
źródło
Ten sprawdza każdy znak specjalny:
źródło
Metoda Java gotowa dla Ciebie, z parametrami
Po prostu skopiuj i wklej i ustaw żądane parametry.
Jeśli nie chcesz modułu, po prostu skomentuj go lub dodaj "if", tak jak zrobiłem to przeze mnie dla specjalnego znaku
źródło
Użyj biblioteki Passay, która jest potężnym interfejsem API.
źródło
Myślę, że to również może to zrobić (jako prostszy tryb):
[Regex Demo]
źródło
Łatwy
("^ (? =. * [0-9]) (? =. * [Az]) (? =. * [AZ]) (? =. * [\\ W _]) [\\ S] {8 , 10} $ ")
(? = cokolwiek) -> oznacza, że wartość dodatnia oczekuje w przód we wszystkich wejściowych ciągach i upewnij się, że ten warunek jest zapisany. próbka (? =. * [0-9]) -> oznacza, że w całym ciągu zapisana jest jedna cyfra. jeśli nie zostanie napisane, zwróć fałsz .
(?! cokolwiek) -> (vice versa) oznacza negatywne oczekiwanie w przód, jeśli warunek jest zapisany, zwraca fałsz .
bliskie znaczenie ^ (warunek) (warunek) (warunek) (warunek) [\ S] {8,10} $
źródło
Wyjaśnienie:
źródło
Ty też możesz to zrobić.
źródło
Przykładowy blok kodu dla silnego hasła:
źródło
Wyrażenie regularne to -
źródło