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 sur des dates [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut regex sur des dates
    Bonjour,

    Je souhaiterais trouver dans une variable une date.
    Le souci principal vient du fait que je n'ai pas le format de la date.
    Je peux avoir aussi bien du format mm/jj/aaaa ou jj/mm/aaaa ou aaa/mm/jj avec des séparateurs différents (/, -, .).

    Avez vous une idée de vérifications avec des regex?

    Merci.
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 36
    Points : 44
    Points
    44
    Par défaut
    Ta question porte sur le faite que tu souhaites sortir la date d'une variable ou sur le fait que tu souhaites ensuite la découper?

    Si tu souhaites simplement la sortir alors concentres toi sur le faite que ta date sera composé de 8 chiffres séparé ou non mais qui seront a la suite.

  3. #3
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    Je souhaite la sortir puis la découper afin de la traiter (vérification, recherche).
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  4. #4
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    J'ai pour le moment ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $patterns = '#(?<![0-9])[0-31]{1,2}[-/.][0-12]{1,2}[-/.][0-9]{1,4}(?![0-9])|';
    $patterns .= '(?<![0-9])[0-12]{1,2}[-/.][0-31]{1,2}[-/.][0-9]{1,4}(?![0-9])|';
    $patterns .= '(?<![0-9])[0-9]{4}[./-][0-12]{1,2}[./-][0-31]{1,2}(?![0-9])#';
    Ce qui prend en compte pas mal de chose mais laisse passer des dates du genre 00/30/5822.
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2010
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 36
    Points : 44
    Points
    44
    Par défaut
    Oui mais cela ne différencie pas 12/12/2009 tu ne sais pas si le premier 12 est le mois ou le jour finalement.

  6. #6
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    En effet, bien que dans ton cas ce n'est pas grave.

    Mais cela, au pire, je le teste après.
    Et si les deux nombres sont inférieurs à 12 je considère que cela peut être du format jj/mm/aaaa ou mm/jj/aaaa.

    Reste le problème du 0.
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  7. #7
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    Bon pour ce qui est du 0 je fais le test après coup.

    Mais la j'ai un souci, lorsque je saisis
    2009/04/15
    cela devrait passer.
    Mais bizarrement je n'ai rien.

    je remets ma dernière version
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $patterns = '#(?<![0-9])[0-31]{1,2}[-/.][0-12]{1,2}[-/.][0-9]{1,4}(?![0-9])|';
    $patterns .= '(?<![0-9])[0-12]{1,2}[-/.][0-31]{1,2}[-/.][0-9]{1,4}(?![0-9])|';
    $patterns .= '(?<![0-9])[0-9]{1,4}[./-][0-12]{1,2}[./-][0-31]{1,2}(?![0-9])#';
    pour moi cela est validé par la dernière condition.
    4 chiffres de 0 à 9 puis un séparateur puis un nombre de deux chiffres compris entre 0 et 12 puis un séparateur puis un nombre de deux chiffres compris entre 0 et 31.

    Voyez vous ce qui bloque?
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  8. #8
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par Phiss Voir le message
    En effet, bien que dans ton cas ce n'est pas grave.

    Mais cela, au pire, je le teste après.
    Et si les deux nombres sont inférieurs à 12 je considère que cela peut être du format jj/mm/aaaa ou mm/jj/aaaa.

    Reste le problème du 0.
    Comment feras-tu pour différencier le 6 juillet 2010 du 7 juin 2010 soit 06-07-2010 par rapport à 07-06-2010 si tu ne sais pas si la date est au format jj/mm/aaaa ou mm/jj/aaaa ?

  9. #9
    Membre émérite
    Avatar de Eric2a
    Homme Profil pro
    Technicien
    Inscrit en
    Septembre 2005
    Messages
    1 225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Corse (Corse)

    Informations professionnelles :
    Activité : Technicien

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 225
    Points : 2 411
    Points
    2 411
    Par défaut
    Salut,

    Citation Envoyé par phiss
    Le souci principal vient du fait que je n'ai pas le format de la date
    Tu n'as pas moyen de l'imposer ?
    Citation Envoyé par ABCIWEB
    Comment feras-tu pour différencier le 6 juillet 2010 du 7 juin 2010 soit 06-07-2010 par rapport à 07-06-2010 si tu ne sais pas si la date est au format jj/mm/aaaa ou mm/jj/aaaa ?
    Il est clair que c'est impossible.

    Sinon, voici un bout de code fonctionnel
    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
    18
    19
    20
    21
    22
    23
    24
    <?php
    $str="
    01.01.2010\n
    31/12/2010\n
    2010-01-01\n
    2010-31-12\n
    06-07-2010\n
    07-06-2010\n
    ";
     
    // Eventuellement l'année (aaaa) + séparateur
    $patterns ='%\b(?:((?:19|20)[0-9]{2})[- /.])?';
     
    // ('mm' + séparateur + 'jj') ou (jj + séparateur + mm)
    $patterns.='(?:(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])|(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012]))';
     
    // (séparateur + aaaa) si l'année n'a pas été spécifiée auparavant
    $patterns.='(?(1)\b|[- /.]((?:19|20)[0-9]{2})\b)%';
     
    if(preg_match_all($patterns, $str, $dates, PREG_SET_ORDER)){
    	foreach($dates as $d){
    		echo "<pre>"; print_r($d); echo "</pre>\n";
    	}
    }
    Nous renvoie
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    Array(
    	[0] => 01.01.2010
    	[1] => 
    	[2] => 01
    	[3] => 01
    	[4] => 
    	[5] => 
    	[6] => 2010
    )
    Array(
    	[0] => 31/12/2010
    	[1] => 
    	[2] => 
    	[3] => 
    	[4] => 31
    	[5] => 12
    	[6] => 2010
    )
    Array(
    	[0] => 2010-01-01
    	[1] => 2010
    	[2] => 01
    	[3] => 01
    )
    Array(
    	[0] => 2010-31-12
    	[1] => 2010
    	[2] => 
    	[3] => 
    	[4] => 31
    	[5] => 12
    )
    Array(
    	[0] => 06-07-2010
    	[1] => 
    	[2] => 06
    	[3] => 07
    	[4] => 
    	[5] => 
    	[6] => 2010
    )
    Array(
    	[0] => 07-06-2010
    	[1] => 
    	[2] => 07
    	[3] => 06
    	[4] => 
    	[5] => 
    	[6] => 2010
    )
    PS : Dans mon exemple, l'expression relative à l'année - (?:19|20)[0-9]{2} - ne traite que les dates comprises entre 1900 et 2099.

  10. #10
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    et date_parse ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $dates = array(
    '01.01.2010',
    '31/12/2010',
    '2010-01-01',
    '2010-31-12',
    '06-07-2010',
    '07-06-2010');
     
    foreach($dates as $date)
    {
        print_r(date_parse($date));
    }

  11. #11
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    Bonjour et merci de vos réponses.

    Alors voilà quelques précisions qui pourraient répondre à vos questions.
    Je ne connais pas le format de la date saisie car l'utilisateur peut être de différents pays.
    Donc un anglais saisira sa date au format mm/jj/aaaa alors qu'un français sera plus du format jj/mm/aaaa.
    Le format avec l'année en premier doit lui aussi être testé.

    Après je ferais une recherche sur jj/mm/aaaa et mm/jj/aaaa si je ne peux pas être sur du format.

    Je vais regarder ce que j'ai avec date_parse et ta solution Eric2a.
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  12. #12
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Si l'utilisateur, quelque soit son pays, rentre la date par l'intermédiaire d'un de tes formulaires, c'est à mon avis plus à ce niveau là qu'il faut travailler. Genre tu modifies le formulaire de saisie des dates (à trois champs) suivant la langue du navigateur...

    Sinon, comme mentionné plus haut, tu auras fatalement des problèmes insurmontables

  13. #13
    Membre actif

    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 191
    Points : 275
    Points
    275
    Par défaut
    heu il existe des fonction sur les dates comme

    date_parse_from_format(string $format , string $date)
    date_parse(string $date)

    la seconde est censée se débrouiller pour trouver la date dans la string

    regarde la doc phph

  14. #14
    Expert éminent sénior

    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2010
    Messages
    5 382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2010
    Messages : 5 382
    Points : 10 410
    Points
    10 410
    Par défaut
    Citation Envoyé par Helfima Voir le message
    heu il existe des fonction sur les dates comme

    date_parse_from_format(string $format , string $date)
    date_parse(string $date)

    la seconde est censée se débrouiller pour trouver la date dans la string

    regarde la doc phph
    Oui mais il n'en reste pas moins que pour une date au format jj/mm/aaaa par rapport au format mm/jj/aaaa aucune fonction ne saura distinguer les deux à tous les coups si on ne sait pas au départ quel format a été utilisé...
    C'est pour cette raison que je dis qu'il faut traiter ce problème avant, au niveau du formulaire

  15. #15
    Membre confirmé Avatar de Phiss
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2005
    Messages
    676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2005
    Messages : 676
    Points : 616
    Points
    616
    Par défaut
    Bonjour,

    Merci de ces réponses.
    Voici du coup ce que j'ai fait.
    Je prends tout ce qui peut ressembler aux formats possibles grâce à ma regex.
    Je teste ensuite les 3 champs pour voir ce que j'ai.
    Si j'ai un doute sur le format je teste plusieurs.
    Ensuite je teste si la date existe.

    Je vous met ma regex si cela peut vous intéresser.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $patterns = '#\b[0-9]{1,4}[./-][0-1]?[0-9][./-][0-3]?[0-9]\b|';
    $patterns .= '\b[0-9]{1,4}[./-][0-3]?[0-9][./-][0-1]?[0-9]\b|';
    $patterns .= '\b[0-1]?[0-9][./-][0-9]{1,4}[./-][0-3]?[0-9]\b|';
    $patterns .= '\b[0-3]?[0-9][./-][0-9]{1,4}[./-][0-1]?[0-9]\b|';
    $patterns .= '\b[0-1]?[0-9][./-][0-3]?[0-9][./-][0-9]{1,4}\b|';
    $patterns .= '\b[0-3]?[0-9][./-][0-1]?[0-9][./-][0-9]{1,4}\b#';
    Je mets en résolu pour l'instant car je ne pense pas pouvoir faire mieux.
    " L'absence diminue les médiocres passions et augmente les grandes, comme le vent éteint les bougies et allume le feu. "
    La Rochefoucauld

  16. #16
    Expert éminent sénior

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Points : 10 726
    Points
    10 726
    Par défaut
    Citation Envoyé par Phiss Voir le message
    Bonjour,

    Merci de ces réponses.
    Voici du coup ce que j'ai fait.
    Je prends tout ce qui peut ressembler aux formats possibles grâce à ma regex.
    Je teste ensuite les 3 champs pour voir ce que j'ai.
    Si j'ai un doute sur le format je teste plusieurs.
    Ensuite je teste si la date existe.

    Je vous met ma regex si cela peut vous intéresser.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $patterns = '#\b[0-9]{1,4}[./-][0-1]?[0-9][./-][0-3]?[0-9]\b|';
    $patterns .= '\b[0-9]{1,4}[./-][0-3]?[0-9][./-][0-1]?[0-9]\b|';
    $patterns .= '\b[0-1]?[0-9][./-][0-9]{1,4}[./-][0-3]?[0-9]\b|';
    $patterns .= '\b[0-3]?[0-9][./-][0-9]{1,4}[./-][0-1]?[0-9]\b|';
    $patterns .= '\b[0-1]?[0-9][./-][0-3]?[0-9][./-][0-9]{1,4}\b|';
    $patterns .= '\b[0-3]?[0-9][./-][0-1]?[0-9][./-][0-9]{1,4}\b#';
    Je mets en résolu pour l'instant car je ne pense pas pouvoir faire mieux.
    bravo t'as recréer data_parse

    sinon pour les intéressés

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $locales = explode(PHP_EOL, `ls /usr/share/locale`);
     
    foreach($locales as $locale)
    {
        if(preg_match('/^[a-z]{2}_[A-Z]{2}$/', $locale))
        {
            $fmt = new IntlDateFormatter($locale ,IntlDateFormatter::SHORT, IntlDateFormatter::NONE);
            printf("<strong>%s</strong> (%s) : %s<br/>\n", Locale::getDisplayRegion($locale, 'fr'), $locale, $fmt->format(time()));
        }
    }
    Afrique du Sud (af_ZA) : 2010-09-24
    Éthiopie (am_ET) : 24/09/2010
    Bélarus (be_BY) : 24.9.10
    Bulgarie (bg_BG) : 24.09.10
    Espagne (ca_ES) : 24/09/10
    République tchèque (cs_CZ) : 24.9.10
    Danemark (da_DK) : 24/09/10
    Autriche (de_AT) : 24.09.10
    Suisse (de_CH) : 24.09.10
    Allemagne (de_DE) : 24.09.10
    Grèce (el_GR) : 24/9/10
    Australie (en_AU) : 24/09/10
    Canada (en_CA) : 10-09-24
    Royaume-Uni (en_GB) : 24/09/2010
    Irlande (en_IE) : 24/09/2010
    Nouvelle-Zélande (en_NZ) : 24/09/10
    États-Unis (en_US) : 9/24/10
    Espagne (es_ES) : 24/09/10
    Estonie (et_EE) : 24.09.10
    Espagne (eu_ES) : 2010-09-24
    Finlande (fi_FI) : 24.9.2010
    Belgique (fr_BE) : 24/09/10
    Canada (fr_CA) : 10-09-24
    Suisse (fr_CH) : 24.09.10
    France (fr_FR) : 24/09/10
    Israël (he_IL) : 24/09/10
    Croatie (hr_HR) : 24. 09. 2010.
    Hongrie (hu_HU) : 2010.09.24.
    Arménie (hy_AM) : 09/24/10
    Islande (is_IS) : 24.9.2010
    Suisse (it_CH) : 24.09.10
    Italie (it_IT) : 24/09/10
    Japon (ja_JP) : 10/09/24
    Kazakhstan (kk_KZ) : 24.09.10
    Corée du Sud (ko_KR) : 10. 9. 24.
    Lituanie (lt_LT) : 2010-09-24
    Belgique (nl_BE) : 24/09/10
    Pays-Bas (nl_NL) : 24-09-10
    Norvège (no_NO) : 24.09.10
    Pologne (pl_PL) : 24-09-2010
    Brésil (pt_BR) : 24/09/10
    Portugal (pt_PT) : 24/09/10
    Roumanie (ro_RO) : 24.09.2010
    Russie (ru_RU) : 24.09.10
    Slovaquie (sk_SK) : 24.9.2010
    Slovénie (sl_SI) : 24. 09. 10
    Serbie (sr_YU) : 24.9.10.
    Suède (sv_SE) : 2010-09-24
    Turquie (tr_TR) : 24.09.2010
    Ukraine (uk_UA) : 24.09.10
    Chine (zh_CN) : 10-9-24
    R.A.S. chinoise de Hong Kong (zh_HK) : 10年9月24日
    Taïwan (zh_TW) : 10/9/24

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

Discussions similaires

  1. Recherche sur des dates
    Par jroy dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 09/02/2006, 08h27
  2. [VB6] Requêtes en BDD sur des dates
    Par pom dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 22/11/2005, 14h04
  3. Index sur des dates?
    Par nicovmd dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 30/06/2005, 14h20
  4. analyse "périodes" basées sur des dates.
    Par Yorglaa dans le forum Oracle
    Réponses: 7
    Dernier message: 22/12/2004, 11h39
  5. Réponses: 9
    Dernier message: 17/01/2004, 10h51

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