2010-06-18 5 views
1

Je travaille sur une expression régulière qui ne retournera vrai que lorsqu'une chaîne de date est dans un format quelque chose comme 'ddd, dd mmm yy'.Regex valider des dates comme "Dim, 20 Juin 10"

Des correspondances valides seraient des valeurs telles que "Dim, 20 juin 10" ou "Lun, 21 juin 10" mais pas "Dimanche 20 juin 10" ou "20 juin 10".

Ceci sera utilisé avec mb_ereg en PHP.

Mes tentatives jusqu'ici m'ont seulement obtenu la moitié du chemin. Toute aide appréciée!

Merci, Dave

Répondre

1

Ceci est une solution. Les jours comme "00" ne sont pas autorisés.

$date = 'Fri, 18 Jun 10'; 
$regex = '#([A-Za-z]{3}), ((?:0[1-9])|(?:(?:1|2)[0-9])|(?:3(?:0|1))) ([A-Za-z]{3}) ([0-9]{2})#'; 
preg_match($regex, $date, $matches); 

// Create Vars out of the matching... 
$day_abbr = $matches[1]; 
$day = $matches[2]; 
$month_abbr = $matches[3]; 
$year = $matches[4]; 

Si vous souhaitez autoriser jours sans zéro, vous devez utiliser ce regex (juste ajouté un questionmark. Cela signifie des dates comme « Dim 8 Jun 10 » sont également valables avec l'expression rationnelle suivante.

$regex = '#([A-Za-z]{3}), ((?:0?[1-9])|(?:(?:1|2)[0-9])|(?:3(?:0|1))) ([A-Za-z]{3}) ([0-9]{2})#'; 
+0

Juste mes 2 cents: Éviter'?: 'de regexes les rendre plus faciles à lire et à comprendre; les utilisateurs peuvent toujours les ajouter si nécessaire. Je les utilise uniquement lorsque la question a quelque chose à voir avec les groupes capturés utilisés pour la lecture ou le remplacement. Aussi '(1 | 2) [0-9]', '3 (0 | 1)' etc peut être écrit comme '[12] [0-9]' et '3 [01]' - je ne sais pas si cela fait toute différence en termes de performances. – Amarghosh

+1

Oui, bien sûr, vous pouvez couper '?:'.Je les ai seulement intégrés pour faciliter les variables après :) Sinon, il aurait été compliqué d'utiliser quelque chose comme: '$ day = $ matches [2], $ year = $ matches [9]' ... est une différence de performance entre l'alternance et les plages dans les regex. Les plages sont toujours mieux pour un tas d'alternatives. Mais l'utilisation de l'opérateur d'alternance '|' n'est acceptable que pour 2-5 alternatives. Donc, votre approche avec '[12] [0-9]' fonctionne aussi parfaitement. Mais comme nous l'avons déjà dit: il n'y a pas de "regex parfaite". Tout le monde a son propre goût;) –

+0

Celui-ci a fonctionné magnifiquement. Merci faileN! – Trindaz

3
"/[a-z]{3}, \\d{2} [a-z]{3} \\d{2}/i" 

Si i drapeau (insensible à la casse) n'est pas pris en charge, remplacer [a-z] avec [a-zA-Z]

Aussi, remplacer [a-z]{3} avec (Sun|Mon|Tue|Wed|Thu|Fri|Sat) et correspondant (Month|List) pour une validation plus stricte.

+0

Je pense que \\ d {2} est à général –

+0

@faileN Si vous voulez le rendre parfaitement infaillible (y compris les noms des mois), vous allez vous retrouver avec un looong et difficile à maintenir regex; Je préfère vérifier la syntaxe avec regex et valider les valeurs avec le code – Amarghosh

+0

@faileN Après tout, toute regex que vous pouvez trouver passera 'Sat, 18 Jun 10' comme valide, mais c'est un Vendredi. – Amarghosh

0

Je ne sais pas pourquoi vous préférez ereg plus preg, mais ici:

$regex = '([A-Z][a-z]{2}), (([012][0-9])|(3[01])|[0-9]) ([A-Z][a-z]{2}) ([0-9]{2})'; 
mb_ereg($regex, "Sun, 31 Jun 10", $regs); 

Bien sûr, si vous voulez convertir en un temps de POSIX, vous auriez besoin de cartographier la partie mois à un entier et utilisez mktime.

+1

' ([012] [0-9]) 'autoriserait' 00' pour une date – Amarghosh

+0

Il serait aussi 'Xxx 00 Yyy 00' – Gordon

Questions connexes