IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Regex format date [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre averti
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    593
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2011
    Messages : 593
    Points : 353
    Points
    353
    Par défaut Regex format date
    Bonjour,

    J'ai un champ date qui prend soit la valeur jj/MM/aaaa ou aaaa.
    J'ai utilisé la regex suivante, mais ça ne marche pas (les dates sous la forme aaaa ne sont pas acceptées). Voyez-vous le problème?
    Merci!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    REGEX_DATE_NAISSANCE = "^((([0]{1}[1-9]{1})|([1-2]{1}[0-9]{1})|([3]{1}[0-1]{1}))"
                + "/(([0]{1}[1-9]{1})|([1]{1}[0-2]{1}))/([0-9]{4}))"
                + "|(([1]{1}([9]{1})[1-9]{1}[0-9]{1}))"
                + "|(([2]{1}([0-9]{3}))) "
                + "|^((([0]{1}[1-9]{1})|([1-2]{1}[0-9]{1})|([3]{1}[0-1]{1}))(([0]{1}[1-9]{1})|([1]{1}[0-2]{1}))([0-9]{4}))"
                + "|^$";

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Tu as un espace qui se ballade à la fin de l'expression concernée :
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre averti
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    593
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2011
    Messages : 593
    Points : 353
    Points
    353
    Par défaut
    Ça m'a complétement échappé, merci!

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Ta pattern n'en reste pas moins erronée, vue qu'elle accepte par exemple la chaîne "18/06/4027 youpi c'est la fête" ou "2001 L'odyssée de l'espace".

    Ce n'est pas facile de s'y retrouver car tu utilises pas mal de caractères inutiles.

    En ce qui concerne les classes de caractères:

    - il est inutile de mettre un caractère unique dans une classe de caractère:[9], il suffit d'écrire 9.
    - pas besoin non plus de définir un rang pour deux caractères successifs: [1-2], écrit simplement [12] (il n'y a rien entre 1 et 2).

    Le quantificateur {1} n'est pas utile, c'est la quantité par défaut.

    Tu mets aussi beaucoup de parenthèses, je ne pense pas qu'elles soient toutes nécessaires. Du coup la lecture n'est pas facilité et les erreurs sont quasi-indétectables.

    Si on écrit la même pattern en version light avec un peu de mise en forme le temps de l'observer, on obtient ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ^ (0[1-9]|[12][0-9]|3[01]) / (0[1-9]|1[0-2]) / [0-9]{4}
     
     |
     
    19[1-9][0-9]
     
     |
     
    2[0-9]{3}
     
     |
     
    ^ (0[1-9]|[12][0-9]|3[01]) (0[1-9]|1[0-2]) [0-9]{4} 
     
     |
     
    ^$
    On a donc cinq branches:

    - JJ/mm/aaaa (avec slashes)
    - aaaa (pour les années 19**)
    - aaaa (pour les années 2***)
    - jjmmaaaa (sans slash)
    - la chaîne vide (est ce que c'est volontaire?)

    Deux choses me sautent au yeux:

    - toutes les branches ne sont pas ancrées à gauche ^ et à droite $ (c'est à cause de ça que les branches 1 et 3 vont réussir avec les exemples de chaînes que j'ai données au début).
    - tu as pris la peine de préciser que seules les années 19** et 2*** sont valides pour le format aaaa, alors que pour les formats jj/mm/aaaa et jjmmaaaa, toutes les années sont permises (d'où l'année 4027 du premier exemple).

    Reconstruisons la pattern pas à pas à partir de ^ jj/mm/aaaa $.

    Au lieu de créer des branches spécialement pour les années seules, on peut rendre optionnels le jour et le mois: ^ (?:jj/mm/)? aaaa $. On peut aussi autoriser mm/aaaa en utilisant le même principe: ^ (?:(?:jj/)?mm/)? aaaa $.
    (?:...) est un groupe non capturant, on l'utilise pour grouper des choses ensemble sans pour autant avoir le projet de les extraire du résultat par la suite contrairement au groupe capturant (...), ce qui permet une petite économie de mémoire et de temps nécessaire à la création d'une nouvelle chaîne.

    Pour autoriser la chaîne vide, même combat: ^ (?:(?:jj/mm/)? aaaa)? $.

    Maintenant on ajoute la version sans slashes, deux façons de le faire:

    - soit on utilise le "ou" logique: ^ (?:(?:jj/mm/|jjmm)? aaaa)? $.
    - soit on utilise une capture et sa référence: ^ (?:(?:jj(/?)mm\\1)? aaaa)? $. Le slash est rendu optionel par le ? et est capturé dans le groupe 1. \\1 ou \1 (suivant le langage et le type de chaîne où est placée la pattern) est la référence au contenu capturé, donc soit c'est un slash, soit c'est une chaîne vide. Ce qui permet d'avoir jjmmaaaa ou jj/mm/aaaa, mais pas jj/mmaaaa ou jjmm/aaaa. L'avantage de cette deuxième manière de faire est qu'on peut facilement rajouter le support d'autres caractères de séparation comme un espace ou un tiret: ^ (?:(?:jj([/ -]?)mm\\1)? aaaa)? $ sans ajouter quinze kilos de code.

    Pour finir il ne reste plus qu'à remplacer:

    - jj par (?:[12][0-9]|0[1-9]|3[01]) (il y a plus de jours commençant par 1 et 2 que par 0 et 3, autant les mettre en premier).
    - mm par (?:0[1-9]|1[0-2]).
    - aaaa par (?:19[0-9]{2}|2[0-9]{3}). (il y a plus de personnes nées au XXe siècle, mais après ça dépend de la tranche d'age visée).

    NB: si tu souhaites extraire par la suite le jour, le mois et l'année, utilises des groupes de capture à la place des groupes non-capturant, mais attention si tu utilises la version avec la capture du slash, la référence deviendra \\2 au lieu de \\1 car les groupes de captures sont numérotés de la gauche vers la droite par ordre d'ouverture.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Membre averti
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    593
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2011
    Messages : 593
    Points : 353
    Points
    353
    Par défaut
    Merci beaucoup CosmoKnacki!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Format date : y'a forcément plus simple...
    Par ZERS dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 02/12/2004, 15h28
  2. Transformation en format Date
    Par Jean-Matt dans le forum Langage SQL
    Réponses: 6
    Dernier message: 16/11/2004, 16h20
  3. Tester un format date
    Par Tapioca dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 30/06/2004, 10h18
  4. interfaces Access et format Date
    Par say dans le forum InterBase
    Réponses: 21
    Dernier message: 10/05/2004, 17h24
  5. Format date
    Par cochet dans le forum Bases de données
    Réponses: 4
    Dernier message: 02/03/2004, 08h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo