Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Przewidywanie w regularnych
Forum PHP.pl > Forum > PHP
adamantd
Witam
przeszukałem trochę internet i nie mogę znaleźć konkretnego rozwiązania a jest ono za pewne bardzo proste i nie będzie stanowiło dla Was wyjadaczy starych PHP-owców żadnego problemu.
  1.  
  2. preg_match("/^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,80}$/", $pass);
  3.  
  4.  
  5.  


(nie jest to moja funkcja)
hasło od 8 - 80 znaków w tym przynajmniej jedna wielka litera i przynajmniej jedna cyfra ponieważ użyte tutaj zostało przewidywanie (którego do końca nie rozumiem)

potrzebuję sprawdzać hasło w którym są przynajmniej 2 duże litery i dwie cyfry (znak specjalny może być ale nie musi)

kombinowałem tak

  1.  
  2.  
  3. if(preg_match("/^[\w\.\-]*[A-Z]{2,}[0-9]{2,}$/", $pass)){
  4.  
  5. if(strlen($pass) >= 8 && strlen($pass) <= 80)
  6. return true;
  7. else
  8. return false;
  9.  
  10. } else {
  11. return false;
  12. }
  13.  
  14.  
  15.  


tu wszystko działa pod warunkiem, że dopasowania są spełniane po kolei a ja chcę, żeby w haśle duże litery lub cyfry były w obojętnie którym miejscu a nie np na końcu.

a więc próbowałem tak

  1.  
  2. preg_match("/^(?=.*[A-Z]{2,})(?=.*[a-z]{2,})(?=.*[0-9]{2,}).{8,80}$/", $pass);
  3.  
  4.  
  5.  


oczywiście ten ostatni przykład nie działa tak jak powinien

jeżeli macie linka do szczegółowego opisu zagadnienia albo możecie mi to wytłumaczyć to z góry dziękuję
pozdo

p.s. -nie zależy mi na gotowcu raczej na wytłumaczeniu, żebym zrozumiał
Crozin
Próbowałeś na siłę użyć skomplikowanych wyrażeń regularnych i nagle z jednego problemu zrobiły się dwa.
1. strlen do sprawdzenia długości hasła. Swoją drogą ograniczanie do 20 znaków jest co najmniej dyskusyjne - dlaczego miałbym nie móc mieć dłuższego?
2. Dwa proste wyrażenia regularne sprawdzające kolejno wystąpienie przynajmniej jednej wielkiej litery (#\p{Lu}#U) oraz jednej cyfry (#\d#).
3. Całość połączona logicznymi AND-ami.
abort
Crozin dobrze gada. Dodatkowo przy jego wersji w bardzo prosty sposób (dodając jeden warunek AND) możesz rozszerzyć wymagania na hasło np. w ten sposób, że będzesz wymagał jakiejś litery lub lakiegoś znaku specjalnego.
Regexpy są fajne - ale w ten sposób to się zajedziesz.
Poza tym, pamiętając, że preg_match zwraca liczbę dopasowanych elementów i używając zaproponowanego Ci sposobu, jesteś w stanie jeszcze bardziej skonkretyzować wymagania na hasło, np. conajmniej dwie duże litery, conajmniej dwie małe litery i conajmniej jedna cyfra, i hasło nie krótsze niż 8 znaków:
Kod
$upper = preg_match('/[A-Z]'/, $entered_pass);
$lower = preg_match('/[a-z]'/, $entered_pass);
$digits = preg_match('/[0-9]'/, $entered_pass);

if ( (strlen ($entered_pass) >= 8) && ($upper >=2) && ($lower >=2) && (digits > 0) ) {
   // kod dla hasła poprawnego
} else {
  // kod dla hasła niepoprawnego
}


Z regexpem tego nie zrobisz. Zresztą, może i zrobisz - ale co się napocisz, to Twoje. Wyrażenia regularne są fajne (i ja je bardzo lubię), ale nie używajmy ich na siłę tam, gdzie da się coś zrobić prościej i szybciej (w sensie pisania kodu na pewno szybciej, w sensie czasu wykonywania przypuszczam, że też)
adamantd
Dzięki -to mi wystarczy, myślałem, że samymi regularnymi będzie bardziej profesional ale chyba rzeczywiście nie ma co sobie utrudniać życie tym bardziej, że nie jestem mistrzem regularnych

a to rozbudowując o znaki specjalne -dużo mniej zastanawiania się i czasu na pisanie niż z tym całym przewidywaniem (?=.*)

  1. $upper = preg_match('/[A-Z]'/, $entered_pass);
  2. $lower = preg_match('/[a-z]'/, $entered_pass);
  3. $digits = preg_match('/[0-9]'/, $entered_pass);
  4. $special = preg_match('/[^a-zA-Z0-9]'/, $entered_pass);
  5.  
  6. if ( (strlen ($entered_pass) >= 8) && ($upper >=2) && ($lower >=2) && ($digits > 0) && ($special >=2)) {
  7. // kod dla hasła poprawnego
  8. } else {
  9. // kod dla hasła niepoprawnego
  10. }



dzięki rozwiązany problem
pozdrawiam
abort
Kod
$special = preg_match('/[^a-zA-Z0-9]'/, $entered_pass);

Aż tak daleko bym ze znakami specjalnymi nie szedł. Dopuściłbym np. tylko te dostępne z klawiatury z shiftem.
W Twoim przypadku dowolna litera spoza alfabetu łacińskiego (np. polskie Ń) będzie znakiem specjalnym. Co chyba nie jest najszczęśliwszym pomysłem. Poczytaj o matchowaniu znaków Unicode. Zresztą, trochę to zależy też od tego, czy piszesz w unicode, czy w ISO-8859-2 (czy nie daj Boże w Win-1250).
adamantd
mogę wcześniej oczyścić z polskich znaków np

  1.  
  2. $entered_pass = strtr($entered_pass, 'ĘÓĄŚŁŻŹĆŃęóąśłżźćń', 'EOASLZZCNeoaslzzcn');
  3.  
  4.  
  5.  


biggrin.gif

wtedy bez względu czy ktoś użyje ą czy a i tak parser przepuści


piszę w ISO-8859-2 bo z utf-8 wiecznie mam jakiś problem

I tutaj dwie sprzeczne informacje
wikibooks:
Do porównywania wzorca z ciągiem służy funkcja preg_match(), która zwraca ilość wystąpień ciągu według podanego wzorca.

http://www.gajdaw.pl/php
Wynikiem funkcji jest zawsze liczba 0 lub 1, która informuje o tym, czy podane wyrażenie zostało odnalezione.

jeżeli mam hasło:
  1.  
  2. $pass = 'mareczekRTE426kupa';
  3.  
  4. echo preg_match("/[A-Z]/", $pass, $m);
  5.  
  6. print_r($m);
  7.  


to funkcja preg_match zwróci wartość 1

a w tablicy $m będzie jedynie R

dlaczego funkcja nie zwraca ilości wystąpień wzorca w stringu?
rzymek01
manual się kłania,
preg_match zwraca 0, 1 albo FALSE, ponieważ po natknięciu się na pasujący wzorzec zatrzymuje się i nie sprawdza dalej,
użyj preg_match_all jeżeli chcesz dojechać do końca wink.gif
adamantd
Rzeczywiście smile.gif dawno w niego nie zaglądałem -a bawiłem się niedawno preg_match_all -dzięki za odświeżenie mojej przyćmionej od dwóch godzin winem głowy hehe -teraz wszystko gra pozdrawiam
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.