Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [regexp] Walidacja nazwiska
Forum PHP.pl > Forum > Przedszkole
piaseq
Chcę stworzyć funkcję waliduj±c± nazwisko, w oparciu o wyrażenia regularne. Zakładam dopuszczenie trzech form nazwiska:
- nazwisko jednoczłonowe, złożone z polskich znaków, zaczynaj±ce się duż± liter±, np. Kowalski
- nazwisko dwuczłonowe, złożone z polskich znaków, np. Kowalska-Brzęczyszczykiewicz
- nazwisko dwuczłonowe, złożone ze znaków a-z w formie trzyliterowego "przedrostka" pisanego małymi literami oraz nazwiska wła¶ciwego zaczynaj±cego się duż± liter±, np. van Deurse. Napisałem takie oto wyrażenie regularne:
  1. <?php
  2. preg_match( '/^(([A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})(-[A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})?)|([a-z]{3} [A-Z][a-z]{2,})$/u', $surname );
  3. ?>


Problem, z którym się borykam polega na tym, że funkcja preg_match() sprawdza do pierwszego wyst±pienia i zwróci 1 w przypadku gdy co najmniej 3 pierwsze znaki pasuj±, więc nazwisko Kow123 zostanie uznane za poprawne.

Rozwi±zanie jest zapewne banalne, ale z powodu mojego małego do¶wiadczenia z wyrażeniami regularnymi lektura manuala nie naprowadziła mnie na nie. Czy kto¶ ma pomysł jakiej innej funkcji użyć lub jak zmodyfikować wyrażenie, abym uzyskał oczekiwany rezultat?
Spyder
A dlaczego nie dodasz ograniczenia na inpucie do wpisywania tylko liter i myslnika i spacji ?
sowiq
Cytat(Spyder @ 22.10.2008, 23:51:52 ) *
A dlaczego nie dodasz ograniczenia na inpucie do wpisywania tylko liter i myslnika i spacji ?

Ponieważ to najgorsze z możliwych rozwiązań i może służyć tylko jako pewnego rodzaju udogodnienie.
Podam Ci co najmniej dwa argumenty:
1) taki sposób opiera się na JS, którą można wyłączyć
2) ktoś może zrobić upload danych z innego formularza - bez walidacji po stronie serwera może Ci zrobić niezłą sieczkę

[edit]
Ja bym to zrobił tak:
Kod
preg_match("/^([a-z]{2,3} [A-ZŁŻ][a-ząęóżźćńłś]{2,})|([A-ZŁŻ][a-ząęóżźćńłś]{2,})(\-[A-ZŁŻ][a-ząęóżźćńłś]{2,})?$/u", $surname);
Spyder
zawsze mozesz dodac to do tego co masz jako 2 stopien filtracji to zeby weliminowac cyfry:

preg_match("/^[0-9\-\ ]+$/",$cos)
sowiq
Twój kod zwróci true tylko wtedy, jeśli $coś będzie składało się wyłącznie z kombinacji cyfr, myślnika i spacji. Tutaj to bezużyteczne.

A moim zdaniem łatwiej jest sprawdzić czy string jest poprawny, niż sprawdzać każdą możliwą kombinację jego niepoprawności.
piaseq
Cytat(sowiq @ 23.10.2008, 00:40:48 ) *
Ja bym to zrobił tak:
  1. <?php
  2. preg_match("/^([a-z]{2,3} [A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})|([A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})(-[A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})?$/u", $surname);
  3. ?>

Z tego co widzę twój kod różni się od mojego głównie zamian± kolejno¶ci wyrażeń po obu stronach alternatywy. To rzeczywi¶cie rozwi±zuje problem z polskimi nazwiskami jedno i dwuczłonowymi. Niestety teraz nazwisko van Deu123 jest uznawane za poprawne.

Wynika z tego, że preg_match() regułę przed alternatyw± sprawdza do pierwszego wyst±pienia wzorca, czyli, za poprawne uznane zostan± wszystkie ci±gi, których pierwsze sze¶ć znaków pasuje do wzorca( np. van Deu*). Natomiast w przypadku wyrażenia znajduj±cego się za znakiem alternatywy sprawdzany jest cały ci±g, więc nazwisko Kow123 jest rozpoznawane jako błędne.

Czy kto¶ mógłby wyja¶nić dlaczego tak się dzieje i co z tym fantem zrobić?
sowiq
Wystarczyło dodać nawias:

Kod
preg_match("/^(([a-z]{2,3} [A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})|([A-ZŁŻ][a-z±ęóżĽćńł¶]{2,}))(\-[A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})?$/u", $surname);


A co do problemu, który opisałe¶ (van Deu*), to nie umiem Ci odpowiedzieć. Wydawać by się mogło, że podany przeze mnie wzorzec nie powinien przepuszczać cyfr... Ale nie jestem znowu jakim¶ tam ekspertem z regex'ów smile.gif
piaseq
Cytat(sowiq @ 23.10.2008, 12:28:29 ) *
Wydawać by się mogło, że podany przeze mnie wzorzec nie powinien przepuszczać cyfr... Ale nie jestem znowu jakim¶ tam ekspertem z regex'ów smile.gif

Ja również s±dziłem, że nie przepu¶ci cyfr. Dla ciebie pomógł za poprzedni± wersję, gdyż rozwi±zała mój problem z nazwiskami polskimi. Nazwiska w formie "van ..." nie s± dla mnie aż tak ważne, ale chociażby z ciekawo¶ci chciałbym poznać rozwi±zanie.

Dlatego ponawiam pytanie do innych użytkowników. Czy kto¶ wie dlaczego wyrażenie:

  1. <?php
  2. preg_match("/^([a-z]{2,3} [A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})|([A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})(-[A-ZŁŻ][a-z±ęóżĽćńł¶]{2,})?$/u", $surname);
  3. ?>

uznaje ci±g "von Cos123" za poprawny pomimo tego, że we wzorcu dopuszczone s± tylko litery?
-Junior-
Ja użyłem takiego wzoru :
$wzor_nazwisko = '/^[A-ZŁŻ]{1}[a-z±ęóżĽćńł¶]*\s?[A-ZŁŻ]{1}[a-z±ęóżĽćńł¶]*$/';

i przed sprawdzeniem poprawno¶ci korzystam z ucwords() żeby każdy wyraz zaczynał się od wielkiej litery.
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.