javascript wyrażenia regularne

0

Witam chcę walidować datę w formacie dzień-miesiąc-rok np: 06-01-2011

Używam takiego kodu:

 
	var oRegExp = new RegExp('^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((?:19|20)\d\d)$');
	if(oRegExp.test(nowa_data)==false) alert("Forma daty jest niepoprawny");

niestety nie waliduje sie poprawnie. Co jest nie tak?

1

Niepotrzebnie używasz konstruktora RegExp zamiast literału wyrażenia regularnego i to powoduje Twoje problemy.

Wyrażenie regularne możesz zdefiniować na dwa sposoby:

// konstruktor RegExp:
var regex1 = new RegExp(stringZeWzorcem, opcjonalnyStringZFlagami);

// literał:
var regex2 = /wzorzec/;

// też literał, ale z flagami 'g' oraz 'm', tak dla przykładu:
var regex2a = /wzorzec/gm;

Jeśli możesz, korzystaj zawsze z literału. Zwięźlej i wygodniej.

Czemu wygodniej?

Zobacz jak nazwałem pierwszy parametr konstruktora: 'stringZeWzorcem'. A w literale jest 'wzorzec'. To duża różnica. Bo stringi w JavaScripcie, jak w praktycznie każdym innym języku, mają specjalne bajery. Specjalne znaki. Np. sekwencje ucieczki rozpoczynające się od znaku \ (bekslesz). Jeśli chcesz umieścić w stringu znak nowej linii, piszesz \n. Jeśli chcesz w stringu ograniczonym cudzysłowami użyć cudzysłowu, piszesz ". I tak dalej. Jeśli chcesz w stringu napisać bekslesz, to piszesz \ -- czyli dwa bekslesze.

Wzorzec opisujący cyfrę to \d. Ale jeśli umieszczasz wzorzec w stringu, musisz ten bekslesz zamienić na dwa, a więc musisz napisać \d. Ty tego u siebie nie masz i samo to powoduje u Ciebie błąd (nie wiem czy jedyny). Popraw to, albo -- lepiej -- użyj po prostu literału wyrażenia regularnego. Literały to jedna z mocniejszych cech JavaScriptu, pozwalają na zwięzły i wygodny zapis.

Poniższe dwa zapisy oznaczają to samo wyrażenie regularne:

var cyfra1 = new RegExp('\\d'); // zauważ podwójny bekslesz
var cyfra2 = /\d/;

Nie muszę chyba udowadniać wyższości tego drugiego zapisu :). Pomiędzy znakami / oraz / to po prostu nie jest zwykły string (ze wzorcem), tylko od razu prawdziwy wzorzec, bez konieczności wstawiania dodatkowych beksleszy. Minus literału jest taki, że nie da się dynamicznie złożyć wzorca czy dopisać flag, a przynajmniej jest to bardzo utrudnione. Do wyrażeń tworzonych dynamicznie używa się więc prawie zawsze konstruktora, ale tak -- używaj bezwstydnie literału.

PS. Jeszcze jedna rada: nie porównuj niczego do false operatorem równości (==). Ze względu na koercję typów, to teoretycznie może raz na ruski rok spowodować nieoczekiwane zachowanie. Jest to minus JavaScriptu. Generalnie radzę unikać stawiania wartości fałszywej (np. false, null, undefined) po którejś ze stron operatora równości.

Zamiast tego można użyć operatora identyczności (===) gdy wiemy, że typy będą się zgadzały. Ale jeszcze lepiej po prostu nie używać żadnego operatora (gdy sprawdzamy czy mamy wartość prawdziwą) lub użyć negacji (gdy szukamy wartości fałszywej). Zaraz się to wyjaśni na przykładzie:

// nie pisz tak:
if (finished == false) {
  alert('Jeszcze nie skończyłem!');
}
// pisz tak:
if (!finished) {
  alert('Jeszcze nie skończyłem!');
}

// i dla wartości prawdziwych
// nie pisz tak:
if (finished == true) {
  alert('Skończyłem!');
}
// pisz tak:
if (finished) {
  alert('Skończyłem!');
}

Ten "PS" to nie jest całkiem bezwzględna rada, choć niektórzy ogarnięci ludzie (Douglas Crockford w "JavaScript - Mocne strony") tak to właśnie traktują. Ja polecam to przemyśleć i samemu podjąć decyzję, który sposób jest czytelniejszy. Ja nie używam operatora porównania dla testów logicznych, bo bez niego warunki wydają mi się zwykle zwięźlejsze i czytelniejsze, no i nie mam potem problemów z koercją typów.

1 użytkowników online, w tym zalogowanych: 0, gości: 1