Preg Partita circonflesso ^ in php
-
21-08-2019 - |
Domanda
Non posso abbastanza ottenere la mia testa intorno a ciò che l'^ sta facendo nel mio preg_match.
if (preg_match('~^(\d\d\d\d)(-(\d{1,2})(-(\d{1,2}))?)?$~', trim($date), $dateParts)) {
echo the $dateparts and do some magic with them
} else {
tell me the date is formatted wrong
}
Come la vedo io questo sta cercando di vedere se la data $ corrisponde al formato che ho letto come 4 decimali - 1 o 2 decimali - 1 o 2 decimali
se lo fa poi partita l'istruzione IF visualizza la data, se non allora si dà un errore di formattazione della data non corretta.
Tuttavia solo di passaggio che l'anno $ Date = '1977' con niente altro (nessun giorno o mese) passa ancora attraverso il vero e visualizza i dateparts, avrei pensato che sarebbe lanciare un errore?
Qualcuno può sottolineare quello che mi manca nell'espressione regolare? Sto indovinando è il ^ o, eventualmente, il? $ Alla fine può significare solo una parte di esso partita?
Soluzione
Non v'è alcuna necessità di gruppo assolutamente tutto . Questo sembra più bello e farà lo stesso:
preg_match('~^\d{4}(-\d{1,2}(-\d{1,2})?)?$~', trim($date), $dateParts)
Questo spiega anche perché "1977
" è accettata - le parti al mese e giorno sono sia opzionale (il punto di domanda fa qualcosa di opzionale)
Per fare quello che dici ( "4 decimali - 1 o 2 decimali - 1 o 2 decimali"), è necessario rimuovere entrambi i gruppi opzionali:
preg_match('~^\d{4}-\d{1,2}-\d{1,2}$~', trim($date), $dateParts)
Il "^
" e "$
" non hanno nulla a che fare con il problema che si sta vedendo. Stanno solo di inizio d'archi e di fine stringa di ancore, facendo in modo che altro di quello che il modello descrive è nella stringa selezionata. Lasciarli fuori e "blah 1977-01-01 blah"
inizierà a partita.
Altri suggerimenti
Prova questo:
'~^(\d\d\d\d)-(\d{1,2})-(\d{1,2})$~'
Il problema è stato l'espressione regolare permetteva il mese e il giorno come optional dalla '?' carattere.
^
e $
ancorare la sequenza per l'inizio e la fine, rispettivamente, della stringa passata. Il ?
è un moltiplicatore, corrispondenti 0 o 1 del modello precedente (in questo caso, il bit parentesi,) .
Il tuo modello corrisponde a un anno o un anno e un mese, o un anno e un mese e data; se si seguono le parentesi, vedrete il <=> finale sta operando sulle parentesi che circondano tutto il modello dopo l'anno.
^ # beginning of string
(\d\d\d\d) #year
(
-(\d{1,2}) #month after a dash
(
-(\d{1,2}) #date after a dash
)? #date optional
)? # month and date optional
$ # end of string
Ok, rompiamo questo per voi:
- '~ ^ (\ d \ d \ d \ d) (- (\ d {1,2}) (-? (\ D {1,2})))? $ ~'
- ~ -. All'inizio e alla fine sono RegExp-delimitatori, quindi non sono realmente parte della espressione regolare
- ^ - Mezzi "Questo è l'inizio della linea"
- Evita corrisponde a metà della corda, ed ancora in modo che l'inizio della stringa deve corrispondere
- (\ d \ d \ d \ d) - Risultati (e catture) quattro cifre, e non è un optional
- Questo potrebbe anche essere scritto come \ d {4}
- (- (\ d {1,2}) (-? (\ D {1,2})))? - Risultati (e cattura) un gruppo opzionale.
- Si dice che se esiste questo gruppo, deve essere un trattino, seguito da una o due cifre (giorno o mese), seguito da un trattino, seguito da una o due cifre (giorno o mese)
- $ - significa fine della stringa, quindi questo, insieme con ^ all'inizio della stringa significa che l'intera stringa deve corrispondere al Regexp .
Alcuni esempi di ciò che questo Regex corrisponderà:
- 1982/8/11
- 1982-30-01
- 8127-99-52
Alcuni esempi che non corrisponderà:
- 82-08-11
- 2009-10
Come si può vedere, questa regex accetterà alcune "date" che non sono realmente date valide, quindi mi sarebbe probabilmente eseguirlo attraverso una sorta di funzione di data-gestione anche, come strtotime .