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 :

Supprimer nombres et tiret en début de chaîne


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut Supprimer nombres et tiret en début de chaîne
    Bonjour à tous,

    Je cherche à remplacer les nombres et un tiret en début de chaîne. Par exemple :

    1234-abcd/abcd/abcd devient abcd/abcd/abcd
    02-abcd/abcd/abcd devient abcd/abcd/abcd
    567-abcd/abcd/abcd devient abcd/abcd/abcd

    etc...il peut y avoir un certain nombre de chiffres suivis d'un tiret, l'ensemble doit disparaître

    J'ai essayé pas mal de truc dont
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $nonumber = preg_replace("/^[0-9-]/", "", $str);
    Mais jamais le résultat obtenu ne convient, alors je veux bien de l'aide.
    D'avance merci.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 486
    Par défaut
    Bonjour,
    Essaie avec :

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    preg_replace("/^[0-9]*-/", "", $str);

  3. #3
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut Supprimer nombres et tiret en début et fin de chaîne
    Bonjour et merci, c'est parfait.

    Cependant, afin que je me couche moins bête, peux-tu m'expliquer ?
    ^ signifie "commence par", c'est exact ?
    [0-9] signifie "n'importe quel chiffre", OK ?

    Mais pourquoi * avant le tiret ?

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 486
    Par défaut
    Citation Envoyé par renaud26 Voir le message
    Bonjour et merci, c'est parfait.

    Cependant, afin que je me couche moins bête, peux-tu m'expliquer ?
    Certainement.

    ^ signifie "commence par", c'est exact ?
    Plus précisément, c'est le marqueur de début d'expression (l'extrémité gauche), à condition d'être le premier caractère de l'expression. Sinon il est traité comme un caractère ordinaire.
    De la même façon, « $ » est le marqueur de fin de chaîne, à condition d'être le dernier caractère de l'expression.

    [0-9] signifie "n'importe quel chiffre", OK ?
    Plus précisément, là encore, c'est la plage des caractères de 0 à 9, soit l'équivalent de (0|1|2|3|4|5|6|7|8|9). Les crochets servent en fait à spécifier une liste de caractères indépendants, mais si tu mets un tiret entre deux d'entre eux, on considéra que c'est une plage, sauf si, comme tu l'as fait, tu le places à la fin (probablement au début aussi mais je n'ai pas testé). Tu peux préciser plusieurs plages au sein d'une même paire de crochets, associées éventuellement à d'autres caractères indépendants. Par exemple : [A-Za-z0-9+_-].

    Mais pourquoi * avant le tiret ?
    Le « * » signifie « 0 fois ou plus » l'expression qui précède. Cette expression est donc soit un caractère, la plupart du temps, soit un groupe de caractères entre crochets ou une sous-expression entre parenthèses.
    De la même façon, « + » signifie « 1 fois ou plus » ce qui précède, mais il est parfois nécessaire « d'échapper » le caractère en le faisant précéder d'un antislash « \ ».

    Il existe également « ? » qui signifie « 0 ou 1 fois », et qui indique donc une expression facultative. Il faut parfois « l'échapper » également.

    En licence d'informatique et en école d'ingénieurs, on les étudie mais en dehors de ce cadre, peu de gens savent qu'il s'agit d'un vrai formalisme mathématique et pas simplement d'un langage défini arbitrairement.

    L'expression a*, par exemple, signifie en fait « A* » (avec l'astérisque en exposant, là où il est censé se trouver en principe), soit littéralement « "a" à la puissance * » où la puissance en question est n'importe quel entier naturel, y compris 0. Soit en fait : « a⁰ ∪ a¹ ∪ a² ∪ a³ ∪ a⁴… ». Par ailleurs, lorsque l'on multiplie deux ensembles, on effectue un produit cartésien, qui consiste à associer chaque élément d'un des ensembles à tous les éléments de l'autre, tour à tour, formant ainsi tous les couples possibles (comme à la bataille navale, avec les lignes et les colonnes). Par conséquent, multiplier des singletons (des ensembles à un seul élément) revient à concaténer ces ensembles et c'est pourquoi on considère que le produit de deux lexons est une chaîne formée de ces deux lexons, d'où l'opérateur . en PHP, par exemple.

    En conséquence, « an » voudrait dire « le caractère "a" multiplié n fois par lui-même » et se résoudrait en « aaaaa… ».

    Pour en revenir à ta propre expression :

    [0-9-] signifie donc « n'importe quel caractère de 0 à 9 ou le tiret, mais une seule fois ». Donc seul le premier caractère de ta chaîne est éliminé ;
    [0-9]*- signifie « n'importe quel caractère de 0 à 9, n'importe quel nombre de fois (y compris 0), suivis d'un tiret ». Donc tous les « éventuels » chiffres sont éliminés, suivi du tiret qui les suit, à condition qu'ils soient tous détectés au départ.

    Si tu ne veux éliminer que les lignes qui commencent réellement par des chiffres et pas celles qui commenceraient directement par le tiret, tu peux remplacer le « * » par « + », ou écrire [0-9][0-9]*- », ce qui revient au même.

  5. #5
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Je te remercie beaucoup d'avoir pris le temps d'écrire cette explication très détaillée. Effectivement, le sujet est pointu et mérite une étude approfondie.
    Je vais creuser car c'est intéressant.
    Bon week-end

  6. #6
    Membre éprouvé Avatar de renaud26
    Homme Profil pro
    Webmaster
    Inscrit en
    Mars 2003
    Messages
    1 365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 365
    Par défaut
    Bonjour à tous,

    Je me permets de réouvrir ce post, car malgré les explications détaillées de Obsidian, je galère encore et toujours avec les regex
    Dans mon exemple, les chiffres et le tirets du début sont bien supprimés, mais je m'aperçois que certaines chaînes en comportent aussi à la fin, suivis de .html :

    Par exemple la chaine de base
    236-abdcefg-0769503905082.html

    doit devenir abcdefg
    Ce qui signifie que 236- du début sautent avec le regex de Obsidian, mais j'ai besoin que -0769503905082.html de la fin de chaîne saute aussi.

    Donc en gros tout ce qui est après le dernier tiret de la chaîne, y compris le tiret lui même.
    Est ce possible en 1 seul passage qui supprimerait 236- et -0769503905082.html ?
    J'ajoute, histoire de corser un peu la chose, que certaines chaines se terminent par abcdefg.html et dans ce cas, seul .html doit sauter.

    Je précise que des chiffres peuvent se trouver dans la chaîne que je veux garder, par exemple abccde25gh....et que ceux-là ne doivent pas sauter

    Merci de votre aide.

  7. #7
    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
    Citation Envoyé par Obsidian Voir le message
    Plus précisément, c'est le marqueur de début d'expression (l'extrémité gauche), à condition d'être le premier caractère de l'expression. Sinon il est traité comme un caractère ordinaire.
    De la même façon, « $ » est le marqueur de fin de chaîne, à condition d'être le dernier caractère de l'expression.
    Attention! ^ marque le début de la chaîne sujet et il peut-être placé n'importe où dans la pattern. En aucun cas il est traité comme un caractère ordinaire, et ce, même s'il n'est pas placé au début. Donc pour figurer le caractère littéral ^ dans une pattern, il doit être échappé \^.

    Cas particulier des classes de caractères: dans une classe de caractères, ^ est utilisé pour figurer la négation de la classe s'il est placé au début de la classe (exemple: [^0-9] tout ce qui n'est pas le rang de 0 à 9). Lorsqu'il n'est pas en première position dans une classe, alors là oui, il n'a plus de signification spéciale (exemple: [0-9^] le rang de 0 à 9 ou un accent circonflexe). Donc si on veut absolument le placer en première position dans la classe, on doit l'échapper d'un antislash, et ce, même s'il définit le début d'un rang (exemples: [^-a] tout ce qui n'est pas un tiret et la lettre minuscule "a", alors que [\^-a] le rang allant de ^ à a, soient les caractères ^, _, ` et a ).

    $ marque la fin de chaîne mais il est ambiguë car ce n'est pas toujours le cas. Il marque aussi la fin de la dernière ligne de la chaîne, si celle-ci est suivie d'un saut de ligne avant la fin de la chaîne, exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    echo preg_match('~abcd$~', 'abcd'); // 1    ok, rien d'étonnant
    echo preg_match('~abcd$~', "abcd\n"); // 1   on est pourtant pas à la fin de la chaîne
    Pour lever l'ambiguïté de $, il faut ajouter le modificateur global D qui correspond à l'option PCRE2_DOLLAR_ENDONLY. Ainsi on obtient bien le resultat escompté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo preg_match('~abcd$~D', "abcd\n"); // 0
    Pour ma part, je préfère utiliser le couple \A \z (A majuscule et z minuscule) pour figurer le début et la fin de chaîne, car ils n'y a pas l'ambiguïté pré-citée et leur signification ne change pas avec le modificateur m.



    Sinon en partant de la pattern de départ, disons ~^[0-9]+-~, on peut ajouter des alternatives séparées pour gérer les autres cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    echo preg_replace('~^[0-9]+-|-[0-9]+(?:\.html)?$|\.html$~D', '', $str);
    // ou encore
    echo preg_replace('~\A[0-9]+-|-[0-9]+(?:\.html)?\z|\.html\z~', '', $str);
    De cette manière, pas besoin de capturer, on se contente d'éliminer.

Discussions similaires

  1. [RegEx] Besoin d'aide pour RegExp
    Par Hyuge dans le forum Langage
    Réponses: 8
    Dernier message: 07/02/2010, 15h09
  2. besoin d'aide pour le composant DBComboBox
    Par jane2002 dans le forum Bases de données
    Réponses: 8
    Dernier message: 28/02/2004, 19h01
  3. [Kylix] besoin d'aide pour installer kylix3
    Par Sph@x dans le forum EDI
    Réponses: 3
    Dernier message: 11/02/2004, 13h53
  4. [TP]besoin d'aide pour commandes inconnues
    Par Upal dans le forum Turbo Pascal
    Réponses: 15
    Dernier message: 03/10/2002, 10h48
  5. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h05

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