[PHP] [Wyrażenia regularne] Dokładnie jedno wystąpienie wzor


(Krzkaczor) #1

Hej!

Dlaczego taki kawałek kodu nie działa? Chciałbym żeby w ifie było true wtedy i tylko wtedy kiedy wzorzec występuje dokładnie jeden raz. Jak widać tak nie jest a kod się wykonuje...

if (preg_match('@[a-zA-Z]{1}@','DUPA')) {

            echo 'nie dziala';

        }

Proszę o pomoc i pozdrawiam


(Sawyer47) #2

Wprawdzie nie znam PHP, ale jeśli działa to tak jak myślę, to:

/^[a-z]$/ - musi pasować od początku do końca napisu (lub linii zależnie od trybu), czyli chyba to o co Ci chodzi

/[a-z]/ - wystarczy, że gdziekolwiek w napisie znajdzie dopasowanie

I tak na marginesie {1} jest raczej zbędne.

Zobacz http://www.php.net/manual/en/regexp.ref ... nchors.php


(M@ster) #3
if (preg_match_all(...) === 1)

{

  ...

}

Tylko że przy wzorcu [a-zA-Z] troszkę mija się to z celem, aczkolwiek domniemam że to tylko przykład :slight_smile:

Swoją drogą /[a-zA-Z]/ można zapisać krócej jako: /[a-z]/i.

Polecam doszkolić się z wyrażeń regularnych :wink:


(Kot-ek) #4

1) "preg_match() returns the number of times pattern matches. That will be either 0 times (no match) or 1 time because preg_match() will stop searching after the first match" - czyli zwraca 0 lub 1 w zależności od dopasowania wyrażenia regularnego w źródle. W Twoim przypadu preg_match zwraca Ci 1 (typ int).

2) nr47 - "{1} jest raczej zbędne" - dlaczego? A jak szuka wystąpienia jednego znaku z podanego zbioru?

3) M@ster - znacznik /i (case insensitive) powoduje, że nie będzie zwracał uwagi na wielkość liter - nie znając znaczenia tego przełącznika i zapisując "skróconą wersję" wyrażenia regularnego przy dalszych jego modyfikacjach (np.: rozpoznanie, czy imię jest zapisane zgodnie z zasadami pisowni - pierwsza litera jest wielka) początkujący użytkownik może zirytować się niezrozumiałymi zachowaniami.

Jaśniej?

Jeżeli nie, to podpowiem, że szukasz wystąpienia pojedynczego znaku (zapis {1}) z przedziału (a-z) oraz (A-Z)) (zapis [a-zA-Z]) w napisie "DUPA". Znajduje D, które zawiera się w przedziale i występuje na pozycji 0, więc zwraca 1. Spróbuj zamienić "DUPA" na "12#$"...


(M@ster) #5

2) {1} jest zbędne gdyż domyślnie znak we wzorcu dopasowywany jest właśnie 1 raz. Ale to nie nic wspólnego z całościowym dopasowaniem wzorca.

Samo preg_match nic mu nie da, jedynie rozróżni czy było dopasowanie czy nie, ale jeśli były 2 to i tak dostanie 1 na wyjściu, dlatego preg_match_all.

Tak poza tym to zgadzam się z Tobą :slight_smile:


(Kot-ek) #6

Fakt M@ster - domyślnie i tak jest {1}... więc SyntaxError jak Cię interesuje szukanie jednego znaku z przedziału, to nie potrzeba go pisać... :slight_smile:


(Krzkaczor) #7

Wielkie dzięki za odpowiedzi :]