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 :

Chercher un espace précédé et suivi d'un alphanumérique [RegEx]


Sujet :

Langage PHP

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 37
    Points : 30
    Points
    30
    Par défaut Chercher un espace précédé et suivi d'un alphanumérique
    Bonjour,

    J'avais besoin de trouver dans des chaines pouvant contenir des numéros de téléphone et des noms prénoms le moyen de supprimer les espaces uniquement entre des chiffres 0690 00 00 00 mon nom.

    À l'aide d'une double boucle sur "0123456789" j'ai donc fait un pattern (0 0|0 1|0 2|0 3| etc… qui fonctionne très bien. Mais je pense qu'il y a certainement un moyen à portée des experts, dont je ne fais pas partie, de minifier cette expression.

    Et il me manque le temps de travailler sur les fondamentaux.

    Je dormirai sûrement moins idiot si une piste était expliquée ici, même brièvement.

    Merci d'avance au(x) spécialiste(s) qui s'y collera(ront).

  2. #2
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Citation Envoyé par ciliaris Voir le message
    j'ai donc fait un pattern (0 0|0 1|0 2|0 3| etc…
    Ben déjà, tu peux utiliser les Classes de caractères :([0-9] [0-9]).
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  3. #3
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    ou encore plus court : \d comme \digit

  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
    Si tu utilises ton expression dans 4D (ou php), tu dois pouvoir utiliser les tests avant et arrières (lookahead et lookbehind) qui ont l'avantage de vérifier les caractères avant et après une position sans pour autant inclure ceux-ci dans le résultat, donc: (?<=[0-9]) (?=[0-9]). Avec cette expression, seul l'espace est renvoyé.

    On peut effectivement remplacer [0-9] par \d, mais attention, car la librairie ICU inclut par défaut tous les chiffres de la catégorie unicode Nd dans \d (ce n'est pas le cas en PHP sauf si on utilise le modificateur u, alors, \d et \p{Nd} deviennent interchangeables).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 37
    Points : 30
    Points
    30
    Par défaut
    Merci à Celira, rawsrc et CosmoHnaki (dans l'odre chronologique des réponses).

    Je vais effectivement commencer par le robuste [0-9] [0-9] auquel j'ai un peu honte de ne pas avoir pensé.

    À propos de \d ou \digit, travaillant effectivement avec 4D, j'ai pu constater qu'il pouvait y avoir des différences d'exécutions, ou du moins des interprétations non désirées. Je pense notamment à \w et variantes qui incluent le caractère _.

    L'expression (?<=[0-9]) (?=[0-9]) est plus pointue. Si j'ai bien compris la position trouvée sera celle de l'espace, et non celle du premier des trois caractères. Le seul avantage que j'y vois c'est qu'il n'y a rien à ajouter à posregex pour déterminer la chaine à conserver avant l'espace trouvé, sinon il faut ajouter 1.

    Et je ne sais pas si le CPU économisé sera plus important que l'éventuelle augmentation de CPU due à celle de la longueur du pattern.

    En tout cas c'est sûr j'en sais plus aujourd'hui.

    Merci.

  6. #6
    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
    \d n'inclura toujours que des chiffres, pas autre chose, le soucis c'est qu'il y aura aussi les chiffres issus d'autres "alphabets" comme ٢ (2 en arabe).
    \w inclut toujours le _, c'est normal, ça fait partie de la définition de cette classe de caractères (lettres, chiffres et underscore). Quand tu veux l'exclure tu peux utiliser [^\W_].

    Si j'ai proposé une solution avec des tests avant/arrière c'est surtout parce qu'ils ne consomment pas les caractères qu'ils testent, ce qui peut être utile dans le cas d'une recherche globale (toutes les occurrences) pour une chaîne du type 1 2 3 4 5 (un seul caractère entre chaque espace): une pattern qui consomme les chiffres avant et après comme [0-9] [0-9], ne trouvera qu'un espace sur deux.
    Mais dans ton cas ce n'est pas vraiment un problème car la seule fonction dont tu disposes est Match regex qui renvoie uniquement la première correspondance. Pour faire une recherche globale tu dois donc le placer dans une boucle et ajuster l'offset de départ à chaque tour.

    L'expression (?<=[0-9]) (?=[0-9]) est plus pointue. Si j'ai bien compris la position trouvée sera celle de l'espace, et non celle du premier des trois caractères. Le seul avantage que j'y vois c'est qu'il n'y a rien à ajouter à posregex pour déterminer la chaine à conserver avant l'espace trouvé, sinon il faut ajouter 1.

    Et je ne sais pas si le CPU économisé sera plus important que l'éventuelle augmentation de CPU due à celle de la longueur du pattern.
    Ne va pas t'imaginer que quelques caractères de plus ou de moins dans une pattern vont changer quoi que ce soit, et penser à optimiser à ce niveau n'a pas trop d'intérêt. À la limite tu peux tenter d'explorer ces pistes:
    • change la pattern de manière à ce qu'elle démarre par un caractère littéral. Ainsi tu pourras profiter d'une optimisation présente sur la plupart des moteurs de regex qui consiste à chercher d'abord les positions où figure ce caractère avec un algorithme rapide. Ça donne ça: ' (?=[0-9])(?<=[0-9] )'
    • en supposant que ta chaîne contienne des blocs de plusieurs chiffres avec espaces, extrait les blocs en entier avec [0-9]+(?: [0-9]+)+ et utilise Replace string pour retirer tous les espaces du bloc, ce qui aura pour effet de réduire le nombre de tour de boucle.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  7. #7
    Nouveau membre du Club
    Inscrit en
    Juin 2007
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 37
    Points : 30
    Points
    30
    Par défaut
    Citation Envoyé par CosmoKnacki Voir le message
    \d n'inclura toujours que des chiffres, pas autre chose, le soucis c'est qu'il y aura aussi les chiffres issus d'autres "alphabets" comme ٢ (4 en arabe).
    \w inclut toujours le _, c'est normal, ça fait partie de la définition de cette classe de caractères (lettres, chiffres et underscore). Quand tu veux l'exclure tu peux utiliser [^\W_].
    Citation Envoyé par CosmoKnacki Voir le message
    Si j'ai proposé une solution avec des tests avant/arrière c'est surtout parce qu'ils ne consomment pas les caractères qu'ils testent, ce qui peut être utile dans le cas d'une recherche globale (toutes les occurrences) pour une chaîne du type 1 2 3 4 5 (un seul caractère entre chaque espace): une pattern qui consomme les chiffres avant et après comme [0-9] [0-9], ne trouvera qu'un espace sur deux.
    Merci CosmoKnacki pour ces utiles précisions de spécialiste.

    La méthode 4D qui traite cette chaine remplace dans l'argument tous les double espaces (ou plus) par un unique espace, sans quoi ni mon ancien pattern ni le nouveau ne fonctionnent.

    Dès que je trouverai du temps, je testerai les CPU selon la méthode que tu préconises. En fait, plus que la longueur de l'expression du pattern, c'est le nombre de tests impliqués qui me fait croire, peut-être à tort, que le CPU sera plus sollicité. Et dans mon imagination [0-9] est un test moins consommateur que ?<=[0-9].

    En tout cas je retiens [^\W_], mais pour moi un pattern est juste une expression que je vais mettre dans une variable au service d'un SGBD. Le contenu de cette variable doit être très aisément compréhensible, même après plusieurs années sans être revisité. On ne fait bien que ce qu'on fait fréquemment.

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

Discussions similaires

  1. [PHP 5.6] Comment supprimer un espace précédé par *
    Par yule dans le forum Langage
    Réponses: 2
    Dernier message: 31/03/2017, 23h26
  2. ch script espace client paiement suivi
    Par yveslens dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 3
    Dernier message: 04/02/2013, 10h43
  3. Réponses: 7
    Dernier message: 08/01/2013, 18h33
  4. mettre en majuscule tous les mot suivi d'un espace
    Par teophane dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 06/07/2007, 16h27
  5. Réponses: 2
    Dernier message: 11/12/2005, 12h05

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