RegEx, aby upewnić się, że ciąg zawiera co najmniej jedną małą literę, wielką literę, cyfrę i symbol


156

Co to jest wyrażenie regularne, aby upewnić się, że dany ciąg zawiera co najmniej jeden znak z każdej z poniższych kategorii.

  • Mała litera
  • Wielkie litery
  • Cyfra
  • Symbol

Znam wzory dla poszczególnych zestawów mianowicie [a-z], [A-Z], \di _|[^\w](Mam je skorygować, prawda?).

Ale jak je połączyć, aby upewnić się, że ciąg zawiera je wszystkie w dowolnej kolejności?


Jaka platforma / dialekt wyrażenia regularnego? Odpowiedź Bartka jest prawidłowa, ale na przykład asercje lookahead nie są wiarygodne w JavaScript.
bobince

Nigdzie w szczególności - uczę się regex. Czy istnieje alternatywa, której można użyć w javascript?
Amarghosh

@bobince Hej, próbuję dowiedzieć się, dlaczego asercje lookahead nie są wiarygodne w Javascript. Czy jest na to wzmianka?
Chris Bier,

@ChrisB: Jest naprawdę zagmatwany błąd IE / JScript: blog.stevenlevithan.com/archives/regex-lookahead-bug
bobince

Odpowiedzi:


349

Jeśli potrzebujesz jednego wyrażenia regularnego, spróbuj:

(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*\W)

Krótkie wyjaśnienie:

(?=.*[a-z])        // use positive look ahead to see if at least one lower case letter exists
(?=.*[A-Z])        // use positive look ahead to see if at least one upper case letter exists
(?=.*\d)           // use positive look ahead to see if at least one digit exists
(?=.*\W])        // use positive look ahead to see if at least one non-word character exists

I zgadzam się z SilentGhost, \Wmoże być trochę szerokie. Zastąpiłbym go takim zestawem znaków: [-+_!@#$%^&*.,?](oczywiście możesz dodać więcej!)


Co by się stało, gdybym zmienił ostatnią .+na .*? Nie mogłem wymyślić przypadku testowego, który się nie udaje .*. Czy są takie same w tym kontekście? „Zero lub więcej znaków” wydaje się być w porządku - po prostu szukam potwierdzenia.
Amarghosh

@Amarghosh: w tym przypadku nie ma to znaczenia. Z powodu pozytywnych wyprzedzeń ciąg zawiera już co najmniej 4 znaki. Więc nie ma znaczenia do zmian .+na .*lub nawet .{4,}w tym zakresie.
Bart Kiers

Jeśli chciałbyś dodać trochę wyjaśnienia, mam problem ze zrozumieniem, w jaki sposób połączenie tych lookaheadów gwarantuje, że co najmniej 1 z każdego zestawu znaków będzie obecny
Sharlike

@Sharlike, nie wiem, jak to przeformułować, aby było łatwiejsze do zrozumienia. Szczególnie w tych małych polach z komentarzami. Zalecam przeczytanie tego: regular-expressions.info/lookaround.html, a jeśli nadal masz pytanie, po prostu zadaj własne. Powodzenia!
Bart Kiers

4
@ikertxu, spróbuj czegoś takiego:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?!.*[&%$]).{6,}$
Bart Kiers,

20

Bart Kiers, Twoje wyrażenie regularne ma kilka problemów. Najlepszym sposobem na to jest:

(.*[a-z].*)       // For lower cases
(.*[A-Z].*)       // For upper cases
(.*\d.*)          // For digits

W ten sposób szukasz bez względu na to, czy na początku, na końcu, czy w środku. Mam dużo problemów ze złożonymi hasłami.


5
Nie sprawdzasz symboli zgodnie z żądaniem OP.
Kazimierz

5

Możesz dopasować te trzy grupy osobno i upewnić się, że wszystkie są obecne. Ponadto, [^\w]wydaje się nieco zbyt szeroka, ale jeśli to, co chcesz, możesz go zastąpić \W.


Dzięki. Nie byłem świadomy \ W. Po prostu sprawdziłem, że pasuje do Not Word. Czy jest jakaś różnica między \ W i [\ W]? Czy [\ W] jest po prostu zbędne?
Amarghosh

@Amarghosh, tak, \Wi [\W]skutkuje tym samym.
Bart Kiers
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.