Preg Match circunflejo ^ en php
-
21-08-2019 - |
Pregunta
No puedo entender muy bien qué está haciendo ^ en mi 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
}
Como lo veo, esto busca ver si la fecha de $ coincide con el formato que leo como 4 decimales: 1 o 2 decimales - 1 o 2 decimales
si coincide, entonces la declaración IF muestra la fecha; si no coincide, genera un error de formato de fecha incorrecto.
Sin embargo, solo pasarlo el año $date = '1977' sin nada más (sin día ni mes) todavía pasa como verdadero y muestra las partes de la fecha, ¿pensaría que arrojaría un error?
¿Alguien puede señalar lo que me falta en la expresión regular?Supongo que es ^ o posiblemente el ?$ al final puede significar que solo coincide con una parte.
Solución
No hay necesidad de agrupar absolutamente todo . Esto se ve más bonito y hará lo mismo:
preg_match('~^\d{4}(-\d{1,2}(-\d{1,2})?)?$~', trim($date), $dateParts)
Esto también explica por qué "1977
" es aceptado - las piezas de mes y día son ambos opcional (el signo de interrogación hace algo opcional)
Para hacer lo que dices ( "4 decimales - 1 o 2 decimales - 1 o 2 decimales"), es necesario eliminar tanto los grupos opcionales:
preg_match('~^\d{4}-\d{1,2}-\d{1,2}$~', trim($date), $dateParts)
El "^
" y "$
" no tienen nada que ver con el problema que está viendo. Se acaba de empezar-de-cuerda y anclajes al final de la cadena, asegurándose de que otra cosa de lo que el patrón describe en la cadena marcada. Dejarlos fuera y "blah 1977-01-01 blah"
comenzará a igualar.
Otros consejos
Prueba esto:
'~^(\d\d\d\d)-(\d{1,2})-(\d{1,2})$~'
El problema fue la expresión regular estaba permitiendo que el mes y día como opcional por el '?' personaje.
^
y $
ancle su patrón al principio y al final respectivamente de la cuerda pasada.El ?
es un multiplicador que coincide con 0 o 1 del patrón anterior (en este caso, el bit entre paréntesis).
Su patrón coincide con un año, o un año y un mes, o un año, un mes y una fecha;Si sigues los paréntesis, verás el final. ?
está operando en los pares que rodean todo el patrón después del año.
^ # 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, vamos a romper esto para usted:
- '~ ^ (\ d \ d \ d \ d) (- (\ d {1,2}) (-? (\ D {1,2})))? $ ~'
- ~ -. En el comienzo y el final son RegExp-delimitadores, por lo que no son realmente parte de la expresión regular
- ^ - Medios "Este es el principio de la línea"
- Evita coincide en el medio de la cadena, y lo ancla para que el inicio de la cadena debe coincidir
- (\ d \ d \ d \ d) - Correspondencias (y capturas) cuatro dígitos, y no es opcional
- Esto también podría ser escrito como \ d {4}
- (- (\ d {1,2}) (-? (\ D {1,2})))? - Correspondencias (y capturas) un grupo opcional.
- Se dice que si existe este grupo, debe ser un guión, seguido de uno o dos dígitos (de día o mes), seguido de un guión, seguido de uno o dos dígitos (de día o mes)
- $ - Significa final de la cadena, así que esto, junto con ^ en el comienzo de la cadena significa que toda la cadena debe coincidir con la expresión regular .
Algunos ejemplos de lo que coincidirá con esta expresión regular:
- 08/11/1982
- 1982-30-01
- 8127-99-52
Algunos ejemplos que no coincidirá con:
- 82-08-11
- 2009-10
Como se puede ver, esta expresión regular aceptará algunos "fechas" que no son realmente fechas válidas, por lo que probablemente ejecutarlo a través de algún tipo de función de la fecha de manipulación también, como strtotime .