2011-01-22 87 views

Respuesta

15

Las expresiones regulares no son adecuados para esta tarea. Por ejemplo, es difícil escribir una expresión regular que coincida con la fecha válida "20080229" pero no con la fecha no válida "20100229".

En su lugar, debe utilizar DateTime.TryParseExact con el formato de cadena "yyyyMMdd". Aquí está un ejemplo:

string s = "20100229"; 
DateTime result; 
if (!DateTime.TryParseExact(
    s, 
    "yyyyMMdd", 
    CultureInfo.InvariantCulture, 
    DateTimeStyles.AssumeUniversal, 
    out result)) 
{ 
    Console.WriteLine("Invalid date entered."); 
}; 
2

Considere el uso de DateTime.TryParseExact para validar la fecha. Puede usar el método para validar y leer simultaneamente el valor DateTime.

Por ejemplo:

DateTime dateValue; 
if (DateTime.TryParseExact(dateString, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateValue)) 
{ 
//Parsed Successfully 
} 
7

Ok, esta es la más bella expresión regular que he construido nunca. Esto explica todos los años bisiestos desde 1582, la introducción del salto. También maneja sin salto cada cuarto siglo. Por ejemplo, 1600 es un salto, pero 1700 no es divisible por cuatro. He probado esto en todos los días entre 1582 y 9999.

var yyyymmdd = new RegExp("^(?:(?:(?:(?:(?:[13579][26]|[2468][048])00)|(?:[0-9]{2}(?:(?:[13579][26])|(?:[2468][048]|0[48]))))(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:0[1-9]|1[0-9]|2[0-9]))))|(?:[0-9]{4}(?:(?:(?:09|04|06|11)(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02(?:[01][0-9]|2[0-8])))))$"); 

Otra versión utilizando guiones

var yyyyDashMmDashDd = new RegExp("^(?:(?:(?:(?:(?:[13579][26]|[2468][048])00)|(?:[0-9]{2}(?:(?:[13579][26])|(?:[2468][048]|0[48]))))-(?:(?:(?:09|04|06|11)-(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)-(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02-(?:0[1-9]|1[0-9]|2[0-9]))))|(?:[0-9]{4}-(?:(?:(?:09|04|06|11)-(?:0[1-9]|1[0-9]|2[0-9]|30))|(?:(?:01|03|05|07|08|10|12)-(?:0[1-9]|1[0-9]|2[0-9]|3[01]))|(?:02-(?:[01][0-9]|2[0-8])))))$"); 

Me encanta que esto funciona para casi todos los idiomas, siempre y cuando ellos apoyan expresiones regulares. Aunque podría decirse que es más sensato utilizar un analizador de fechas específico para el idioma, creo que esto muestra el poder y la elegancia de las expresiones regulares.

Aquí hay un image del patrón con barras en Regexper si quiere verlo.

Cuestiones relacionadas