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: Contrôle de codes postaux internationaux [RegEx]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut Regex: Contrôle de codes postaux internationaux
    Bonjour,

    J'ai une fonction de contrôle des codes postaux en fonction du pays de destination.
    Lorsque le nombre de caractères est fixe, ma fonction accepte les codes postaux trop longs. Pourquoi?
    Code php : 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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    // Contrôle du code postal
    function ctl_postcode($postcode, $country='') {
    	// voir https://fr.wikipedia.org/wiki/Code_postal
    	$country = strtolower($country);
    	// Codes à 3 chiffres
    	if (in_array($country, ['mg'])) $pattern = "#^\d{3}$#";
    	// Codes à 4 chiffres
    	if (in_array($country, ['at', 'au', 'az', 'be', 'ch', 'dk', 'fl', 'hu', 'lu', 'md', 'mk', 'ph', 'tn', 'za'])) $pattern = "#^\d{4}$#";
    	// Codes à 5 chiffres
    	elseif (in_array($country, ['ba', 'de', 'dz', 'es', 'fi', 'fr', 'gt', 'hr', 'it', 'lk', 'lt', 'ma', 'me', 'my', 'mx', 'rs', 'sa', 'ua'])) $pattern = "#^\d{5}$#";
    	// Codes à 6 chiffres
    	elseif (in_array($country, ['by', 'cn', 'co', 'ec', 'in', 'kz', 'kg', 'ro', 'sg', 'uz'])) $pattern = "#^\d{6}$#";
    	elseif (in_array($country, ['il'])) $pattern = "#^\d{7}$#";
    	else {
    		switch ($country) {
    			case 'ar': // Argentine
    				$pattern = "#^[A-Z][0-9]{4}[A-Z]{3}$|^[0-9]{4}$#";
    				break;
    			case 'bj': // Bénin
    				$pattern = "#^\d{2}[A-Z]{2}\d{4}$#";
    				break;
    			 // Brésil + Cambodge CCCCC-CCC
    			case 'br':
    			case 'kh':
    				$pattern = "#^\d{5}\-\d{3}$#";
    				break;
    			case 'ca':
    				$pattern = "#^[a-zA-Z]{1}[0-9]{1}[a-zA-Z]{1}[ -]{1}[0-9]{1}[a-zA-Z]{1}[0-9]{1}$#";
    				break;
    			case 'gb':
    				$pattern = "#^[A-Z]{1,2}[A-Z0-9]?[0-9] [0-9][A-Z]{2}$#";
    				break;
    			// CCC CC
    			case 'gr':
    			case 'se':
    			case 'sk':
    			case 'cz':
    				$pattern = "#^\d{3} \d{2}#";
    				break;
    			case 'ht': // Haïti
    				$pattern = "#^HT-\d{4}#";
    				break;
    			case 'ie':
    				$pattern = "#^[A-Z][0-9][A-Z0-9] [A-Z][0-9]{3}$#";
    				break;
    			case 'jp':
    				$pattern = "#^[0-9]{3}-[0-9]{4}$#";
    				break;
    			case 'nl':
    				$pattern = "#^[1-9][0-9]{3} [A-B]{2}$#";
    				break;
    			case 'pl': // Pologne CC-CCC
    				$pattern = "#^[0-9]{2}-[0-9]{3}$#";
    				break;
    			case 'pt': // Portugal CCCC-CCC
    				$pattern = "#^[0-9]{4}-[0-9]{3}$#";
    				break;
    			case 'us':
    				$pattern = "#^\d{5}([ -][0-9]{4})?$#";
    				// (^\d{5}(?:[\s]?[-\s][\s]?\d{4})?$)
    				break;
    			case 'ta':
    				$pattern = "#^[1-9]{1}[0-9]{2}$#";
    				break;
    			default:
    				return true;
    				break;
    		}
    	}
    	if (preg_match($pattern, $postcode)) return true;
    	else return false;
    }

  2. #2
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Des exemples ?

    Un conseil. php a la bonne idée de gérer des tableaux avec des clés alphanumériques. Pourquoi ne pas en profiter ?

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function ctl_postcode($postcode, $country='') {
    
    $toto = array();
    
    $toto["at"] = "la regexp";
    $toto["au"] = "la regexp";
    ...
    $toto["za"] = "la regexp";
    if (isset($toto[$country])) {
      if(preg_match($toto[$country], $postcode)) return true; else return false;
    } else {
      return true;
    }
    }

  3. #3
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    Et puis comme on est bien fainéants...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php
    $toto = array();
     
    //---- les groupes
    $toto = array_merge($toto,array_fill_keys(['at', 'au', 'az', 'be', 'ch', 'dk', 'fl', 'hu', 'lu', 'md', 'mk', 'ph', 'tn', 'za'], "#^\d{4}$#"));
    $toto = array_merge($toto,array_fill_keys(['ba', 'de', 'dz', 'es', 'fi', 'fr', 'gt', 'hr', 'it', 'lk', 'lt', 'ma', 'me', 'my', 'mx', 'rs', 'sa', 'ua'], "#^\d{5}$#"));
    $toto = array_merge($toto,array_fill_keys(['by', 'cn', 'co', 'ec', 'in', 'kz', 'kg', 'ro', 'sg', 'uz'], "#^\d{6}$#"));
     
    //---- Les solitaires
    $toto['ar'] = "#^[A-Z][0-9]{4}[A-Z]{3}$|^[0-9]{4}$#";
    $toto['bj'] = "#^\d{2}[A-Z]{2}\d{4}$#";
     
    var_dump($toto);

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    @badaze : bien vu !

    Citation Envoyé par moimp Voir le message
    ...Lorsque le nombre de caractères est fixe, ma fonction accepte les codes postaux trop longs...
    @moimp : je ne comprends pas cette phrase.
    Explique mieux (exemple ?)

  5. #5
    Membre Expert
    Avatar de badaze
    Homme Profil pro
    Chef de projets info
    Inscrit en
    Septembre 2002
    Messages
    1 412
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets info
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2002
    Messages : 1 412
    Par défaut
    D’autant plus qu’avec un code postal français ça fonctionne bien.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Merci badaze pour les suggestions d'amélioration. L'idée du tableau associatif est excellente.
    Pour en revenir à la question initiale, j'ai posté ma demande parce que mon code ne marche pas à tous les coups:
    Par exemple, si le pays est madagascar (code = 'mg'), l'expression accepte les codes de longueur >=3 et non pas uniquement ceux de longueur strictement égale à 3.
    Un code français à 6 chiffres a également été accepté mais je n'arrive pas à reproduire le cas.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Je ne comprends pas très bien pourquoi les contrôles qui ne marchaient pas avec ma version fonctionnent avec la tienne alors que les regex sont les mêmes. Quoi qu'il en soit le code terminé selon la ta version est exactement deux fois moins long que le mien. Bravo et Merci.

  8. #8
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 986
    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 986
    Par défaut
    Voilà pourquoi ça ne marche pas avec le code de Madagascar:

    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
     ### cette condition réussie et la pattern correcte est affectée ###
    if (in_array($country, ['mg'])) $pattern = "#^\d{3}$#";
     
    ###  mais comme ici tu as un if au lieu d'un elseif, toutes les conditions vont être testée  ###
    // Codes à 4 chiffres
    if (...) ...;
    // Codes à 5 chiffres
    elseif (...) ...;
    // Codes à 6 chiffres
    elseif (...) ...;
    elseif (in_array($country, ['il'])) $pattern = "#^\d{7}$#";
    ### comme toutes les conditions précédentes on échouées tu passes dans le else puis dans le switch ###
    else {
        switch ($country) {
            case 'ar': // Argentine
    	// ...
            ### pour finalement atterrir ici ou la clause "default:" te fais quitter la fonction en renvoyant "true". La pattern n'a jamais été testée.
            default:
                return true;
                break;
        }
    }
     
    if (preg_match($pattern, $postcode)) return true;
    	else return false;

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

Discussions similaires

  1. Se procurer bases de données ISBN, UCP, Codes postaux...
    Par zatomik dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 26/10/2010, 19h55
  2. Liste des villes et codes postaux
    Par CynO dans le forum Services
    Réponses: 11
    Dernier message: 27/09/2007, 01h07
  3. [MySQL] Code postaux et contrôle
    Par jarod71 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 25/04/2006, 21h30
  4. Tri par Codes Postaux + Noms d'entreprises
    Par matperino dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/07/2005, 14h04
  5. [VCL] Scroller un contrôle par code
    Par sbeu dans le forum Composants VCL
    Réponses: 3
    Dernier message: 31/03/2004, 10h39

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