2010-03-26 11 views
21

Znalazłem wyrażenie regularne dla MM/DD/RRRR na http://www.regular-expressions.info/regexbuddy/datemmddyyyy.html, ale nie sądzę, że używam go poprawnie.Co to jest wyrażenie regularne MM/DD/RRRR i jak używać go w php?

Oto mój kod:

$date_regex = '(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d'; 

$test_date = '03/22/2010'; 
if(preg_match($date_regex, $test_date)) { 
    echo 'this date is formatted correctly'; 
} else { 
    echo 'this date is not formatted correctly'; 
} 

Kiedy uruchamiam to, że wciąż powtarza „data ta nie jest poprawnie sformatowana”, kiedy należy powiedzieć coś przeciwnego. Jak ustawić to wyrażenie regularne w php?

+0

daje również 'w arning: preg_match(): Nieznany modyfikator "[" –

+0

Istnieje mnóstwo poprawnych odpowiedzi poniżej, ale jedną rzeczą, o której nie wspomniałem, jest to, że ten wzór nie wydobywa prawidłowo roku ... tylko stulecia. Musiałbyś zmienić go na '/ (0 [1-9] | 1 [012]) [- /.](0[1-9]|[12][0-9]|3[01]) [- /.] (19 | 20 \ d \ d)/'. –

+0

@fiXedd: Wygląda na to, że nie próbuje niczego wydobyć ... –

Odpowiedz

39

Problem dotyczy jednego z delimiterów i znaków z ewidencją (jak wspomnieli inni). To będzie działać:

$date_regex = '/(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/'; 

$test_date = '03/22/2010'; 
if(preg_match($date_regex, $test_date)) { 
    echo 'this date is formatted correctly'; 
} else { 
    echo 'this date is not formatted correctly'; 
} 

pamiętać, że dodatek do przodu-slash na początku i na końcu wyrażenia i escapped (z back-slash) w przód ukośniki w szyku.

Aby zrobić krok dalej, ten wzór nie wyda właściwie roku ... tylko stulecia. Musisz go zmienić na /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]((?:19|20)\d\d)/ i (jak Jan wskazał poniżej), jeśli chcesz się upewnić, że cały łańcuch pasuje (zamiast jakiegoś podzbioru), powinieneś pójść z czymś bardziej podobnym do .


Jak wspominają inni, strtotime() może być lepszym rozwiązaniem, jeśli jesteś po prostu staramy się datę na zewnątrz. Może on parsować prawie każdy powszechnie używany format i da ci unikalny znacznik czasu. Można go używać tak:

$test_date = '03/22/2010'; 

// get the unix timestamp for the date 
$timestamp = strtorime($test_date); 

// now you can get the date fields back out with one of the normal date/time functions. example: 
$date_array = getdate($timestamp); 
echo 'the month is: ' . $date_array['month'];  
+1

Grupa "rok" nie działa zaraz po zmianie. Musisz odizolować alternację we własnej grupie, najlepiej nie przechwytywania: '((?? 19 | 20) \ d \ d)'. –

+0

Nie, to, co dostajesz za nie testowanie go w datach w latach 1900 do 1999. Nie przetestowałeś go również na '1212/12/201010'. –

+0

Czy ktoś może mi wyjaśnić to wyrażenie regularne? Ledwo to rozumiem. –

5

Prawdopodobnie lepiej będzie użyć metody strtotime(), która skonwertuje prawie każdy możliwy do odczytania format daty na unikalny znacznik czasu. - http://php.net/manual/en/function.strtotime.php

+1

+1 Uzgodniono. Chociaż strtotime jest prawdopodobnie wolniejszy. – jps

+0

W jaki sposób strtotime pomoże mi sprawdzić, czy użytkownik wprowadził ciąg znaków w formacie MM/DD/RRRR? Czy możesz podać mi przykład? Jestem całkowicie zdezorientowany. – zeckdude

+1

strtotime może odczytać datę w dowolnym formacie i można sprawdzić, czy zwrócona wartość jest poprawna. – jps

0

Twój regex potrzebuje ograniczników:

/(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/

+0

Potrzebne są również ukośniki odwrotne - te z '\ d's. EDYCJA: A ucieczki z klas postaci wymagają podwójnych ucieczek. –

+0

To również nie przechwytuje poprawnie rok, to tylko uchwycić 19 lub 20 ... nie 2010. –

+1

@Billy: odwrotne ukośniki nie muszą być escaped, jeśli otaczający literał ciągu używa cudzysłowów, np. ''/(19 | 20) \ d \ d/"'. W istocie, PHP jest dość wybaczający, nawet w podwójnych cudzysłowach, ale zazwyczaj najlepiej jest używać cudzysłowów. –

3

można użyć funkcji checkdate() również. Nie potrzebujesz wyrażeń regularnych.

$str="03/22/2010"; 
list($mth,$day,$yr)=explode("/",$str); 
var_dump(checkdate($mth,$day,$yr)); 
+0

+1 dla prostego, nieregexowego rozwiązania. Jednak przykład może wymagać trochę pracy. Wierzę, że pasowałoby do ciągu '' 03/22/2010/2011 "' lub '" 03/22/2010 /// "' –

+1

@Frank Farmer: explode ("/", $ str, 3); może? To ograniczy eksplozję do 3 elementów, co oznacza, że ​​03/22/2010/2011 pojawi się jako {03, 22, 2010/2011}, gdzie część roku jest oczywiście nieważna. – Duroth

5

Potrzebujesz około correct delimiters wokół wzoru.

$date_regex = '~(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d~'; 
1

Aby użyć tej regex do sprawdzania poprawności dat w kodzie PHP, trzeba prawidłowo sformatować go jako ciąg z dodatkowych ograniczników regex jak ciąża PHP funkcje wymagają. Trzeba także dodać kotwice zmusić regex, aby dopasować cały ciąg (albo nie pasuje):

$date_regex = '%\A(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d\z%'; 

$test_date = '03/22/2010'; 
if(preg_match($date_regex, $test_date)) { 
    echo 'this date is formatted correctly'; 
} else { 
    echo 'this date is not formatted correctly'; 
} 

Oczywiście, wywołanie biblioteki byłoby lepiej w tej sytuacji. Wyrażenie regularne zezwala na nieprawidłowe daty, takie jak 31 lutego.

Wyrażenie regularne może być przydatne, jeśli chcesz skanować ciąg w poszukiwaniu dat. W takim przypadku nie potrzebujesz kotwic. Nadal możesz potrzebować dodatkowej kontroli, aby wykluczyć nieprawidłowe daty. To zależy od tego, czy twoje dane wejściowe będą zawierały tylko ważne daty, czy nie.

1

ten sprawdza ważne daty z MM/DD/1960 do MM/DD/2014

Również akceptuje termin jak M/D/YYYY i 0M/0D/YYYY

^(?:[1-9]|0[1-9]|1[0-2])/(?:[0-9]|0[1-9]|1[0-9]|2[0-9]|3[0-1])/(?:20[6-9][0-9]|20[0-1][0-4])$ 
1

Regex autora tej kwestii jest prawie poprawne. Data nie jest potwierdzone, ponieważ wzorzec powinien być:

pattern="^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|20)\d\d$" 

czy być wyobraźnia:

pattern="^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$" 

Należy pamiętać, że ten wzór sprawdza tylko dla formatu daty i MAX/wartości min dla indywidualnego elementy daty. Oznacza to, że wpis użytkownika powinien być sprawdzany pod kątem ważności daty w funkcji JavaScript i/lub serwera (np. 29 lutego nie powinno być dozwolone, jeśli rok nie jest skokiem).

Na marginesie, jeśli chcesz, aby umożliwić jednocyfrowy (powiedzmy za miesiąc), zmienić część miesiąca do

([0-9]|0[1-9]|1[012]) 

Wyjaśnienie:
[0-9] - jednocyfrowy od 0 do 9
lub
0 [1-9] - dwie cyfry od 01 do 09
lub
1 [012] - dwie cyfry ograniczone do 10, 11, 12

Powiązane problemy