Esta expresión regular valida las marcas de tiempo, p. 2018-02-12 00:55:22:

[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]) (2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9]

Sin embargo, la marca de tiempo debe validarse paso a paso:

201 => true
201a => false
2018- => true
20189 => false

¿Hay una buena extensión de expresión regular (corta)?

......

1
Thomas Müller 3 mar. 2018 a las 22:48

3 respuestas

La mejor respuesta

Debido a que su pregunta tiene la etiqueta de JavaScript, voy a suponer que está haciendo una validación "paso a paso" como "onkeyup" o similar. El siguiente patrón validará su cadena de fecha y hora a medida que se está construyendo (incluyo una cadena vacía como válida para que no se active ninguna marca cuando está vacía; pero puede cambiar a \d{1,4} si desea actuar en cadenas vacías )

Estoy usando \d siempre que sea posible para reducir la longitud del patrón.

El modificador de patrón x está en juego con mi patrón volcado, para facilitar la lectura. Cuando aplica esto a su proyecto, puede compactarlo todo y eliminar la bandera x.

Estoy usando grupos que no capturan por costumbre; dado que probablemente solo coincida, puede usar grupos de captura si lo desea.

Demo de patrones

Modelo:

~
^
(?:
\d{0,4}|
\d{4}-|
\d{4}-[01]|
\d{4}-(?:0[1-9]|1[0-2])|
\d{4}-(?:0[1-9]|1[0-2])-|
\d{4}-(?:0[1-9]|1[0-2])-[0-3]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s[0-2]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d)|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:[0-5]|
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[0-1])\s(?:2[0-3]|[01]\d):[0-5]\d:[0-5]\d
)
$
~
x
1
mickmackusa 8 mar. 2018 a las 22:26

Regex no es la forma de hacer esto.

Heres una función simple. Utiliza una buena fecha en el formato correcto, quita el número de caracteres del frente que se ha ingresado y lo combina con el vale ingresado, luego verifica si es válido

function validateDate($date)
{
    $fakedate = "2018-02-12 00:55:22";
    $date .= substr($fakedate, strlen($date));
    $format = 'Y-m-d H:i:s';
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

var_dump(validateDate('201')); bool(true)
var_dump(validateDate('201a')); bool(false)
var_dump(validateDate('2018-')); bool(true)
var_dump(validateDate('20189')); bool(false)
0
miknik 3 mar. 2018 a las 20:30

Puede combinarlo para obtener 2 bloques de información general.

Haga coincidir gradualmente los delimitadores de formulario - - : :
mientras permite / empareja segmentos malos.

Al final obtienes información sobre el progreso del formulario.
Y también los segmentos de forma.

Usted prueba el progreso del formulario a través de grupos de captura 2,4,6,8,10

Usted prueba los elementos de fecha / hora a través de grupos 1,3,5,7,9,11

Sin embargo, solo necesita probar los elementos hasta el grupo máximo en el formulario
Progreso.

^(?:(?:([0-9]{4})|\d*)(-(?:(0[1-9]|1[0-2])|\d*)(-(?:(0[1-9]|[1-2][0-9]|3[0-1])|\d*)([ ]+(?:(2[0-3]|[01][0-9])|\d*)(:(?:([0-5][0-9])|\d*)(:(?:([0-5][0-9])|\d*))?)?)?)?)?)$

Formateada

 ^    
 (?:
      (?:
           ( [0-9]{4} )                          # (1)
        |  \d* 
      )
      (                                     # (2 start)
           -
           (?:
                ( 0 [1-9] | 1 [0-2] )                 # (3)
             |  \d* 
           )
           (                                     # (4 start)
                -
                (?:
                     ( 0 [1-9] | [1-2] [0-9] | 3 [0-1] )   # (5)
                  |  \d* 
                )
                (                                     # (6 start)
                     [ ]+ 
                     (?:
                          ( 2 [0-3] | [01] [0-9] )              # (7)
                       |  \d* 
                     )
                     (                                     # (8 start)
                          :
                          (?:
                               ( [0-5] [0-9] )                       # (9)
                            |  \d* 
                          )
                          (                                     # (10 start)
                               :
                               (?:
                                    ( [0-5] [0-9] )                       # (11)
                                 |  \d* 
                               )
                          )?                                    # (10 end)
                     )?                                    # (8 end)
                )?                                    # (6 end)
           )?                                    # (4 end)
      )?                                    # (2 end)
 )
 $

Segmentos a través de si los grupos de captura coinciden.

0
user557597user557597 3 mar. 2018 a las 20:20