2011-01-22 11 views

risposta

15

Le espressioni regolari non sono adatti per questo compito. Ad esempio, è difficile scrivere un'espressione regolare che corrisponda alla data "20080229" valida, ma non alla data "20100229" non valida.

Invece si dovrebbe usare DateTime.TryParseExact con la stringa di formato "yyyyMMdd". Ecco un esempio:

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

Considerare di utilizzare DateTime.TryParseExact per convalidare la data. È possibile utilizzare il metodo per convalidare e leggere il valore DateTime in modo silente.

Ad esempio:

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

Ok, questa è la più bella espressione regolare che abbia mai costruito. Questo spiega tutti gli anni bisestili dal 1582, l'introduzione del salto. Gestisce anche il non salto ogni quarto secolo. Ad esempio, 1600 è un salto ma 1700 non è però divisibile per quattro. Ho provato questo in tutti i giorni tra il 1582 e il 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])))))$"); 

Un'altra versione utilizzando trattini

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])))))$"); 

Mi piace che questo funziona per quasi tutte le lingue, a patto che essi supportano regex. Mentre è probabilmente più sensato usare un parser data specifico per la lingua, penso che questo mostri la potenza e l'eleganza delle espressioni regolari.

Ecco uno image del modello con barre in Regexper se si desidera vederlo.

Problemi correlati