Blog webdeveloperski Patryk yarpo Jar

Walidacja formularzy wyrażeniami regularnymi

Autor wiadomości Czerwiec 4, 2011

Wyrażenia regularne są to wzorce, które opisują łańcuch symboli [wikipedia].

Za pomocą wzorców regularnych możemy sprawdzić, czy danych ciąg znaków "pasuje" do naszego wzorca, np. mając listę ludzi:

  1. Jan Kowalski
  2. Zdzisław Nowak
  3. 123312 23232^%^%$
  4. Janko Muzykant

Od razu widzimy, że pozycja 3 nie pasuje. Dlaczego? Przecież porównując "Jan Kowalski" == "Zdzisław Nowak" także otrzymamy `false'. Otóż, wszystkie pozostałe pozycje na liście spełniają pewne kryteria jakie sobie założyliśmy:

<wzorzec>{numer}{kropka}{spacja}{imię}{spacja}{nazwisko}{enter}</wzorzec>

JavaScript posiada wbudowane mechanizmy obsługi wyrażeń regularnych (ang. regular expressions, w skrócie regex/regexp).

W tym wpisie pokażę, jak za pomocą wyrażeń regularnych walidować dane przekazywane przez użytkownika w formularzu.

Quick start

Na początek odpalmy jakiś prosty przykład. W zamierzeniu ma on robić to co przykład z wpisu o walidacji.

<html>
<head>
    <title>Walidacja formularza RegExp</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script type="text/javascript">
    function validation()
    {
        var re = /[a-zA-Z]{3}/; // 1

        if (!re.test(document.getElementById('example').value)) // 2
        {
            alert('Wpisz co najmniej 3 znaki');
            return false;
        }
        return true;
    }
    </script>
</head>
<body>
    <form action="#" onsubmit='return validation()'>
        <input type="text" name="example" id="example"/>
        <input type="submit" />
    </form>
</body>
</html>

demo online

Może słowo wyjaśnień :). W linii "1" tworzymy obiekt wyrażenia regularnego. Mówimy, jakiego wzorca ciągu znaków otrzymujemy. Nie wpisujemy na sztywno ciągu znaków, a jedynie "przepis" na ten wzorzec. Mówi on:

"Ma być to klasa znaków, od litery 'a' do 'z' lub 'A' do 'Z', mają to być 3 znaki".

W kwadratowych nawiasach podajemy klasy znaków, jakich oczekujemy. W nawiasach klamrowych podajemy liczbę pasujących do wyrażenia regularnego przypasowań z podanego ciągu.

W linii "2" sprawdzamy za pomocą funkcji `test', czy podany jako parametr ciąg znaków spełnia nasz regExp.

Wątpliwości: być może ciekawi Cię, czy dla ciągu znaków "abcd" funkcja `validation' zwróci `true' czy `false'. W klamrowym nawiasie podaliśmy 3, tak więc powinno zwrócić `false' - prawda? Nie. Zwróci prawdę, a to dlatego, że istnieją dwa prawidłowe przypasowania (sic!):

  1. abcd
  2. abcd

Nie powiedzieliśmy, czy wyrażenie regularne ma szukać od samego początku ani czy ma szukać do końca. Szuka po prostu ciągu 3 znaków podanych w zadanej klasie, które są położone jeden za drugim. Tak więc ciąg znaków (małych lub wielkich liter) o długości większej bądź równej 3 będzie spełniał warunek.

Aby wyszukać ciąg znaków o długości dokładnie 3, należy zmodyfikować nasze wyrażenie regularne:

var re = /^[a-zA-Z]{3}$/;

Znak `^' (w tym przypadku) oznacza "szukaj od początku przekazanego ciągu", z kolei znak `$' oznacza "szukaj od końca". Oba znaki jednocześnie oznaczają "szukaj ciągu znaków składających się z tych podanych w kwadratowym nawiasie, o długości dokładnie 3".

Bardziej skomplikowany przykład

Skoro już znamy totalne podstawy (podstawy podstaw:)) wyrażeń regularnych w JavaScript, to czas na trochę bardziej skomplikowany przykład. Załóżmy, że mamy formularz z takimi polami:

  • imię i nazwisko
  • data urodzenia
  • e-mail
  • strona www

Najpierw określmy, które pola mają zawierać jakiego rodzaju dane:

pole wartość regExp
name {imię}{spacja}{nazwisko}
zarówno imię jak i nazwisko - od 2 do 30 liter
/^[a-z]{2,30} [a-z]{2,30}$/i
date {dzień}{kropka}{miesiąc}{kropka}{rok}
dzień i miesiąc powinny mieć dokładnie 2 cyfry
rok dokładnie 4
/^\d{2}\.\d{2}\.\d{4}$/
email {login}{małpa}{serwer}{kropka}{domena}
(wersja uproszczona) login i serwer składać się może z liter, cyfr, kroki lub podkreślnika. Wielkość liter nieistotna
/^[a-z0-9\._%-]+@[a-z0-9\.-]+\.[a-z]{2,4}$/i
site {http://}
(wersja uproszczona) ciąg znaków zaczynający się od "http://". Wielkość liter nieistotna
/^http\:\/\//i

Słowo wyjaśnienia (kliknij tu, aby rozwinąć)

Teraz czas na kod formularza:

<html>
<head>
    <title>Walidacja formularza RegExp</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <script type="text/javascript">
    function validation()
    {
        var form =  document.getElementById('info-form'),
            rules = { // 1
                'name' : /^[a-z]{2,30} [a-z]{2,30}$/i,
                'date' : /^\d{2}\.\d{2}\.\d{4}$/,
                'email': /^[a-z0-9\._%-]+@[a-z0-9\.-]+\.[a-z]{2,4}$/i,
                'site' : /^http\:\/\//i
            };

        for (var elem in rules) // 2
        {
            if (form[elem])
            {
                if (!rules[elem].test(form[elem].value)) // 3
                {
                    alert('Pole ' + elem + ' ma nieprawidłową wartość');
                    form[elem].style.background = 'red';
                    return false;
                }
                else
                {
                    form[elem].style.background = '';
                }
            }
        }
        alert('Wszystkie pola wypełnione poprawnie - wysyłam!');
        return true;
    }
    </script>
</head>
<body>
 <form action="#" id="info-form" onsubmit='return validation();'>
        Imię i nazwisko: <input type="text" name="name" id="name"/><br />
        Data urodzenia: <input type="text" name="date" id="date"/><br />
        E-mail: <input type="text" name="email" id="email"/><br />
        WWWW : <input type="text" name="www" id="www"/><br />
        <input type="submit" value="gotowe" />
    </form>
</body>
</html>

demo online

W powyższym kodzie przydałoby się dodać odrobinę komentarza.

  1. Tworzą obiekt [tablicę asocjacyjną] w której kluczami są nazwy pól formularza, a wartościami obiekty wyrażeń regularnych.
  2. Sprawdzam dla wszystkich pozycji w tablicy `rules', czy istnieje taki element w formularzu i jeśli istnieje...
  3. ... sprawdzam, czy jego aktualna wartość jest zgodna z wyrażeniem regularnym

Warto zauważyć, że wyrażenia regularne w tym przykładzie nie są zbyt wysublimowane - łatwo jest podać dane nieprawidłowe, choćby "99.99.0000" zostanie przyjęte jako właściwa data. Chodziło jednak o pokazanie samej idei, a nie podanie najlepszych możliwych wyrażeń regularnych.

Słowo wyjaśnienia

W powyższym wpisie wykorzystywałem literał wyrażeń regularnych /wyrażenie/flagi. Można jednak także używać konstruktora:

var re = new RegExp("wyrażenie", "flagi")

Warto zajrzeć

Jeśli podoba Ci się idea wyrażeń regularnych warto zajrzeć na stronę:

Co dalej?

Komentarze (0) Trackbacks (0)

Brak komentarzy.


Leave a comment

 

Brak trackbacków.