Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php][regex] wyrażenie regularne z wymuszeniem określonych znaków
Forum PHP.pl > Forum > PHP
AxZx
witam,

czy jest możliwość ułożenia takiego zapytania, które wymuszałoby obecność w stringu minimum 3 liter oraz dopuszczałoby podanie 1 myślnika?

w skrócie:
minimum 3 litery, maksimum 1 myślnik.

po różnych kombinacjach wydaje mi się, że nie za bardzo. ale nie jestem w te klocki za dobry dlatego proszę o pomoc.

pozdrawiam
zzeus
[a-zA-Z] - określa zakres znaków które mogą zostać użyte
[]{3} - mówi że muszą wystąpić 3 znaki z zakresu podanego w []
? - mówi że znak który występuje przed nim musi wystąpić 0 lub 1 raz

Chyba się nie pomyliłem, a to co potrzebujesz już sobie chyba sam złożysz

Pozdrawiam
AxZx
Cytat(zzeus @ 14.05.2009, 08:11:58 ) *
[a-zA-Z] - określa zakres znaków które mogą zostać użyte
[]{3} - mówi że muszą wystąpić 3 znaki z zakresu podanego w []
? - mówi że znak który występuje przed nim musi wystąpić 0 lub 1 raz

Chyba się nie pomyliłem, a to co potrzebujesz już sobie chyba sam złożysz

Pozdrawiam


doceniam Twoje dobre chęci, ale właśnie chodzi o to złożenie.
te podstawy, o których napisałeś znam.

np takie coś:
  1. <?php
  2. $nazwisko = '- aaa - aaa -';
  3.  
  4. if(preg_match('#[a-zA-Z]{3}-{0,1}#', $nazwisko)){
  5.    echo 'ok';
  6. }else{
  7.    echo 'źle';
  8. }
  9. ?>

wyświetla ok, a nie powinno.
zzeus
  1. <?php
  2. preg_match('/^[a-zA-Z]{3}-?$/', $nazwisko)
  3. ?>


może tak ?
AxZx
Cytat(zzeus @ 14.05.2009, 12:44:21 ) *
  1. <?php
  2. preg_match('/^[a-zA-Z]{3}-?$/', $nazwisko)
  3. ?>


może tak ?


a widzisz, czyli to jednak nie takie proste:)
nie ma co zgadywać - tego już próbowałem.

EDIT:
a może trzeba sprawdzać to w dwóch etapach? najpierw sprawdzić czy w całym ciągu znaków jest więcej niż jeden myślnik, jeśli tak od razu odrzucić. drugi etap to sprawdzenie czy występują minimum 3 litery.

hmm przydałby się jeszcze jeden etap do sprawdzenia czy nie występują jakieś inne znaki niż litery i myślnik.

jeżeli nie da się tego wykonać jednym zapytaniem to chyba tak to będę musiał zrobić.
kacka
Mam nadzieje, że niczego nie pominąłem:)
  1. <?php
  2. if (preg_match('/^(-?[A-Za-z]{3,}|[A-Za-z]{1}-?[A-Za-z]{2,}|[A-Za-z]{2}-?[A-Za-z]{1,}|[A-Za-z]{3}-?||[A-Za-z]*-[A-Za-z]*)$/', $subject)) {
  3.    # Sukces
  4. } else {
  5.    #Porażka
  6. }
  7. ?>
AxZx
Cytat(kacka @ 15.05.2009, 10:02:17 ) *
Mam nadzieje, że niczego nie pominąłem:)
  1. <?php
  2. if (preg_match('/^(-?[A-Za-z]{3,}|[A-Za-z]{1}-?[A-Za-z]{2,}|[A-Za-z]{2}-?[A-Za-z]{1,}|[A-Za-z]{3}-?||[A-Za-z]*-[A-Za-z]*)$/', $subject)) {
  3.    # Sukces
  4. } else {
  5.    #Porażka
  6. }
  7. ?>


skomplikowane;)
dzięki, zaraz sprawdzę.

EDIT:
sprawdziłem (mam gotową funkcję + przykłady złych i dobrych stringów). niestety Twój regex nie zdał egzaminu.
widocznie jakieś kosmetyczne zmiany trzeba wykonać.
webdice
W jednym wyrażeniu regularnym raczej tego nie zrobisz (przynajmniej mi nic do głowy nie przychodzi). Na Twoim miejscu najpierw bym sprawdził czy w tekście występują minimum czy litery:

  1. <?php
  2. preg_match ('#[a-zA-Z]{3,}#', $nazwisko)
  3. ?>


a następnie policzył bym ilość myślników i zastosował odpowiedniego ifa.
AxZx
Cytat(webdice @ 15.05.2009, 11:49:36 ) *
W jednym wyrażeniu regularnym raczej tego nie zrobisz (przynajmniej mi nic do głowy nie przychodzi). Na Twoim miejscu najpierw bym sprawdził czy w tekście występują minimum czy litery:

  1. <?php
  2. preg_match ('#[a-zA-Z]{3,}#', $nazwisko)
  3. ?>


a następnie policzył bym ilość myślników i zastosował odpowiedniego ifa.


czyli tak jak myślałem.
wczoraj to opisałem, że najlepiej to pewnie jest w 3 etapach zrobić. najpewniej i przejrzyście:)
dzięki.
kacka
Jednak pominąłem: winksmiley.jpg

  1. <?php
  2. if (preg_match('/^(-?[A-Za-z]{3,}|[A-Za-z]{1}-?[A-Za-z]{2,}|[A-Za-z]{2}-?[A-Za-z]{1,}|[A-Za-z]{3,}-?|[A-Za-z]{2,}-?[A-Za-z]{2,}|[A-Za-z]{2,}-?[A-Za-z]{1})$/', $subject)) {
  3.    # ok
  4. } else {
  5.    # źle
  6. }
  7. ?>


Działa dla:
Kod
-kacper
k-acper
ka-c
kacp-er
kacper-
kac-
kac-p
k-asd
kacper-r


Nie działa dla:
Kod
-ka
k-a
ka-
k-a
ka-
k-
-k


Ale IMO pokazuje to tylko dlatego, żeby pokazać że się DA:)
webdice
Cytat(kacka @ 15.05.2009, 14:37:55 ) *
(...) Ale IMO pokazuje to tylko dlatego, żeby pokazać że się DA:)


Masz racje da się smile.gif, wydajność też musi być rewelacyjna tongue.gif.
kacka
Przynajmniej fajnym kodem w skrypcie można poszpanować;P
AxZx
Cytat(kacka @ 15.05.2009, 14:37:55 ) *
Jednak pominąłem: winksmiley.jpg
Ale IMO pokazuje to tylko dlatego, żeby pokazać że się DA:)


masz racje. da się:) trzeba było wszystkie możliwe kombinacje wpisać. ale z moich nieskomplikowanych testów wynika, że zapomniałeś o dwóch kombinacjach.
- kolawski
kolawski -

nie wiem czy to jest poprawna możliwość podania nazwiska. chyba nie.
ale ja założyłem, że mają być minimum 3 litery maksimum 1 myślnik. a te dwa stringi spełniają to założenie.

tak w ogóle to jest walidacja nazwiska, której problem kiedyś na forum był poruszany ale chyba nie było tak pozytywnych rezultatów:)
kacka
Cytat(AxZx @ 15.05.2009, 14:07:14 ) *
- kolawski
kolawski -


Nie mówiłeś nic o spacjach:)

Kod
-kolawski
kolawski-


Testy przechodzi, ze spacjami oczywiście już nie;)
AxZx
Cytat(kacka @ 15.05.2009, 16:22:53 ) *
Nie mówiłeś nic o spacjach:)

Kod
-kolawski
kolawski-


Testy przechodzi, ze spacjami oczywiście już nie;)


masz racje, zapomniałem. przepraszam.

ale nie dając możliwości podania spacji można by wpłynąć na podniesienie poziomu irytacji wprowadzającego dane.
bo przecież ktoś może zechcieć podać kowlsa-junger a ktoś inny poda kowlsa - junger.
w ostatnim etapie można by usuwać jeszcze podwójne spacje, tzn zamieniać je na jedną spację.

ja przygotowałem taki test:
  1. <?php
  2. echo 'ok:<br />';
  3. echo sprawdz('kowalski').'<br />';
  4. echo sprawdz(' - kowalski').'<br />';
  5. echo sprawdz('stanowski-kowalski').'<br />';
  6. echo sprawdz('kowalski -').'<br />';
  7. echo sprawdz('kowalski - stosdfdsfki').'<br />';
  8. echo sprawdz('- kowalski').'<br />';
  9. echo sprawdz('różą k - owalski').'<br />';
  10.  
  11. echo '<br />';
  12. echo 'not ok:<br />';
  13. echo sprawdz('k -owa -lski').'<br />';
  14. echo sprawdz('---- kowalski').'<br />';
  15. echo sprawdz('--').'<br />';
  16. echo sprawdz('-').'<br />';
  17. echo sprawdz('').'<br />';
  18. echo sprawdz(' -- - aaa').'<br />';
  19. echo sprawdz('- a - a - a - ').'<br />';
  20. echo sprawdz('a - a').'<br />';
  21. echo sprawdz('- a -').'<br />';
  22. echo sprawdz('- a').'<br />';
  23. ?>
kacka
Możesz wcześniej preg_replace i usuwanie spacji;)
AxZx
Cytat(kacka @ 15.05.2009, 23:11:37 ) *
Możesz wcześniej preg_replace i usuwanie spacji;)


całkiem spacji nie mogę usunąć. bo jak już napisałem, ktoś może będzie chciał podać swoje nazwisko tak: kowlsls - ndfndf
a jak usunę to później musiałbym zgadywać gdzie dał spacje a gdzie nie dał.

ciekawe czy nikt się nie przejmuje poprawnością podanego nazwiska czy po prostu trzeba pisać takie długie regexy zawierające wszystkie możliwe kombinacje.
kacka
Jeśli chodzi o mnie, to przyjął bym że nazwisko jest w formacie nazwisko-nazwisko bez spacji (lub ze spacjami), poprawianie użytkownika to nie koniec świata.
MySQL
Cytat(AxZx) *
minimum 3 litery, maksimum 1 myślnik

To oczywiście jest troszkę inne rozwiązanie bo wykorzystujące funkcję, a nie wyrażenie regularne. Nie wiem jak z wydajnościa, która będzie lepsza. Czy wyszukiwanie za pomocą wyr. reg. korzystające z teorii automatów skończonych czy też korzystając z tej funkcji i jednej pętli for (złożoność liniowa).

A oto sama funkcja:
  1. <?php
  2. function myReg($r)
  3. {
  4.   $l = 0; // licznik liter
  5.   $m = 0; // licznik myslnikow
  6.  
  7.   for($i = 0, $len = strlen($r); $i < $len; $i++)
  8.   {
  9.      if((($r[$i] >= 'A') && ($r[$i] <= 'Z')) || (($r[$i] >= 'a') && ($r[$i] <= 'z')))
  10.      {
  11.         $l++;
  12.      }
  13.      if($r[$i] == '-')
  14.      {
  15.         $m++;
  16.      }
  17.   }
  18.   return (($l >= 3) && ($m <= 1));
  19. }
  20. ?>

W każdym razie do czasu aż ktoś napisze dobrze to wyr. reg. (jeżeli już koniecznie musisz użyć wyr. reg.) możesz skorzystać z tej funkcji. Oczywiście zalecane byłoby żebyś dopisał jeszcze warunek na początku tej funkcji na wypadek, gdyby argument funkcji nie był łańuchem znaków, ale... winksmiley.jpg
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.