Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Preg_match walidacja danych
Forum PHP.pl > Forum > PHP
Lethys
Witam,

Od dwóch dni główkuje jak zrobić poprawnie sprawdzenie danych przesyłanych w formularzu.

Chcę aby były akceptowane tylko litery małe, duże + polski alfabet + spacje + cyfry

Próbowałem :

  1. // pierwsza próba
  2. preg_match('#^[A-z0-9ąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*$#is', $zmienna)
  3.  
  4. //druga próba
  5. preg_match('/^([a-żA-Ż0-9_] [a-żA-Ż0-9_]+)$/i', $zmienna)
  6.  
  7.  


Przegooglowałem, poczytałem, próbowałem na wiele sposobów ale nadal mi nie działa tak jak chcę.
Noidea
Pierwszy sposób jest dobry, tylko zapomniałeś spacji w klasie znaków i błędnie zdefiniowałeś litery (zerknij na http://www.asciitable.com/ jakie znaki masz między dużą literą A a małą literą z)
Lethys
Poprawiłem znaki, żeby było A-Za-z. Chyba o to Ci chodziło.

Obecnie to wygląda tak:


  1. preg_match('#^[a-zA-Z0-9ąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*$#is', $zmienna)




Obecnie nadal nie działa, jak zmienna ma w sobie np. ;" to nadal przechodzi przez moją "zaporę ochronną" smile.gif

jak dodać spację, jak zrobić żeby uzyskać mój żądany efekt?
mortus
Spacja to \040, zatem cały regexp powinien wygldać tak:
^[a-zA-Z0-9ąćęłńóśźżĄĆĘŁŃÓŚŹŻ\040]*$
Przełączniki si nie są Ci potrzebne. Powinno działać, więc jeśli nie działa, to pokaż więcej kodu.
by_ikar
spacja to również \s

Kod
preg_match('#^[\w\d\sąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*$#is', $zmienna);


Jeżeli dajesz flagę "i", to nie musisz pisać a-zA-Z, wystarczy że dasz a-z lub \w. Ta flaga ignoruje wielkość liter.

mortus
Cytat(by_ikar @ 21.11.2011, 11:51:07 ) *
spacja to również \s

Kod
preg_match('#^[\w\d\sąćęłńóśźżĄĆĘŁŃÓŚŹŻ]*$#is', $zmienna);


Jeżeli dajesz flagę "i", to nie musisz pisać a-zA-Z, wystarczy że dasz a-z lub \w. Ta flaga ignoruje wielkość liter.

\s to nie tylko spacja, a biały "pusty" znak, jak np. znak nowej linii, czy tabulator.
Lethys
Jeszcze mam 2 problemy z datą:

Pierwsza sprawa:

Format daty: 2011-11-19

Preg_match :

  1. if (!preg_match('/^([0-9]{4})[-\.]([0-9]{1,2})[-\.]([0-9]{1,2})/', $data_utworzenia)) {
  2. $problem = TRUE;
  3. echo("<p id='uwaga'><h2>Błędne dane do usunięcia. DATA $data_utworzenia</h2></p>");
  4. }


czyli niby wszystko ok ale zmieniam w bazie danych datę na np. 2011-11-19as i mi nie wykrywa, że data nie jest poprawna.


Druga sprawa:

Jak zrobić preg match pod taki tekst:

941387/Jakis-cel
377871/Robienie-obiadu

To będzie coś takiego?? :

  1. preg_match('/^([0-9]{6})[\057][a-zA-Z\055])/', $data_utworzenia))
zegarek84
w pierwszym przypadku zakończ wyrażenie dolarem, czyli:
'/^([0-9]{4})[-\.]([0-9]{1,2})[-\.]([0-9]{1,2})$/'
w drugim nawet nie patrzysz gdzie otwierasz a gdzie zamykasz nawiasy + najlepiej tak robić wyrażenie coby je zaczynać i kończyć ^$
'/^([0-9]{6})\/([a-zA-Z\-]*)$/'
Lethys
Mam jeszcze jeden przypadek.

W moim portalu user może wrzucać linki z różnego rodzaju poradnikami.

Linki te są wzucane do bazy więc chciałbym odrzucić "link" powodujące sql_injection.


Zrobiłem to w ten sposób:

  1. if(preg_match('#^[\:\;\"\'\<\>]*$#is', $_POST['link']) and $_POST['link']!=NULL){


Ale przepuszcza mi link gdzie jest np. ;

Jak zrobić aby te znaki nie były akceptowalne?
zegarek84
skoro chciałeś wykluczyć zestaw znaków i uzyskać jego odwrotność (wszystkie oprócz) to daszek stosuje się na początku klamry [^znaki], przy czym nie myl tego daszka z daszkiem na początku wyrażenia regularnego, gdzie on oznacza, iż wyrażenie ma się dopasowywać od początku... znak "*" znaczy tyle co {0,}, czyli 0 lub wiele, tutaj raczej chciałeś zastosować znak "+" który znaczy {1,} co najmniej 1 znak (zwróć uwagę na przecinek)... wszystko zależy, jak dokładnie chcesz sprawdzać te adresy - można by wymodzić jakieś ogólne wyrażenie ale to wcześniej ktoś musiałby podać jakieś ograniczenia....

Jeśli chodzi o SQL iniection to przede wszystkim zainteresuj się PDO i funkcjami prepare, lub chociaż mysqli i też funkcjami prepare...

Zależy, jak daleko chcesz iść ze sprawdzaniem poprawności adresów - czasami ktoś się pomyli i choć adres strukturę będzie miał poprawną to nie będzie nigdzie prowadził - można to też sprawdzić ale to inny temat...

ogólne wyrażenie na adres mogło by wyglądać (przy czym nie chce mi się sprawdzać jakie są najdziwniejsze znaki i bodajże znak ";" chyba też może występować, podobnie jak procenty czy polskie znaki (wszystko zależy, kto z jakiej przeglądarki skopiuje i jakie kodowanie otrzyma..)

przykładowe wyrażenie mogło by wyglądać np. w ten sposób:
Kod
/^(?:https?\:\/\/)?(?:[wW]{3}\.)?(?!.*(?:[\-\/\.]){2,})[a-zA-Z0-9_\-\.]{2,}\.[a-zA-Z]{2,5}(?:\/[a-zA-Z0-9_!\/\|\+\%\.\-\?\=\&\#]*)?$/

(?!.*(?:[\-\/\.]){2,}) - to znaczy, że nigdzie dalej ma się nie dopasować do występujących pod rząd naraz 2 znaków "-" lub "." lub "/"
jeśli jest jeszcze część poza domeną to reszta musi się zaczynać od znaku "/"
tam sobie możesz pododawać jakieś dozwolone / zabronione znaki...

SKORO LINKI WKLEJAJĄ Z ZEWNĄTRZ, TO ZAŁOŻYŁEM, IŻ DOMENA W LINKU TEŻ MUSI BYĆ [a-zA-Z0-9_\-\.]{2,}\.[a-zA-Z]{2,5}, choć teraz wprowadzili, że i w domenie może być nawet cyrylica ^^, więc zamiast tego można by jakiś bardziej ogólny schemat napisać... zależy co chcesz ^^
Lethys
Dziękuje za tak wyczerpującą odpowiedź smile.gif

Tylko zrodziło mi się pytanie w głowie czy nie łatwiej po prostu wypisać zakazane znaki (które w adresie strony nie występują) i jeżeli dane adres je posiada to blokować dalszy skrypt?

Druga sprawa, czy blokując wszystkie "niebezpieczne" dane w formularzu i POST przez właśnie preg_match nie bronie się przed sql_injection?
zegarek84
Cytat(Lethys @ 23.11.2011, 10:28:14 ) *
Druga sprawa, czy blokując wszystkie "niebezpieczne" dane w formularzu i POST przez właśnie preg_match nie bronie się przed sql_injection?

A może tak zamiast się przed tym bronić to uczynić je poprawnymi i bezpiecznymi??

Wszystko zależy, jakie masz typy formularzy...

Firma: Jan Kowalski "Primawera"

I co - w powyższym nie pozwolisz na wprowadzanie cudzysłowów?? Odpowiednio spreparowany kod jeśli dane potem nie są odpowiednio wyświetlane pozwala na rozwalenie kodu html... gdy do wyświetlania wystarczy coś w stylu htmlspecialchars. Fakt, jeśli w bazie nie chcesz mieć śmieci to jakoś minimalnie pod kontem poprawności powinno to się kontrolować... co do SQL iniection to jak już wspomniałem najlepiej prepare w PDO...

o adresie strony to wspomniałem właśnie o tym - czyli chyba prościej w drugą stronę no to np. (ale baaardzo ograniczona filtracja)
Kod
/^(?!.*(?:[\-\.]){2,})[^\s]{2,}\.[a-zA-Z]{2,5}(?:\/[^\s]*)?$/

dodaj sobie tam do tablicy znaków zakazanych co tam uważasz... i początek (?!.*(?:[\-\.]){2,}) jest tam nie potrzebny...
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.