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 avec exclusion conditionnelle


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 avec exclusion conditionnelle
    Bonjour,

    Je bloque sur une regex qui me permettrait de trouver des saut de lignes d'une chaine qui ne sont pas placés au bon endroit.

    problème :
    J'ai lu un fichier et stocké le contenu dans une chaine de caractère.
    Cette chaine est formatée.
    Chaque ligne doit commencée par comme suivant : A ou B ou C suivit d'un point virgule suivit de A ou B suivit d'un point virgule ou de la chaine END.
    Exemple
    Pour lire je recherche les \n pour ensuite traiter ma ligne.
    Mais je rencontre un problème que je souhaite résoudre.
    dans mes fichiers je me retrouve avec des sauts de lignes au milieu de ma ligne. Du coup je ne traite plus mes lignes correctement.
    Vu que mes lignes commencent toutes par la même chose je voulait faire la regex suivante pour retrouver les sauts de ligne intempestifs et les modifier en espace.

    Je cherche donc toutes les sauts de lignes qui ne sont pas suivit par la lettre A ou B ou C puis ; puis A ou B ou ;.
    J'ai donc un truc du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #(\x0A.*)(\x0A)([^A|B|C;A|B;].*\x0A)#
    Mais cela ne retourne pas ce que je veux.
    Cela ne me retourne pas tous les sauts de lignes qui sont suivi par un A ou un B ou un C mais cela ne prend pas en compte la chaine complète que je veux.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    A;B;etc;
    B;A;etc2;
    A;B;chaine 
    avec saut de ligne;etc3;
    A;B;etc4;
    C;A; chaine avec saut de ligne mais ligne suivantes commençant par lettre de la liste
    B;etc5;
    C;A;etc6;
    dans cet exemple, cela ne me retourne que la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    A;B;chaine 
    avec saut de ligne;etc3;
    alors que je voudrais avoir la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    C;A; chaine avec saut de ligne mais ligne suivantes commençant par lettre de la liste
    B;etc5;
    Savez vous comment je peux tourner ma regex pour obtenir ce que je souhaite?
    " 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 expert
    Avatar de Spartacusply
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mai 2011
    Messages
    1 723
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 1 723
    Points : 3 274
    Points
    3 274
    Par défaut
    Ca m'a tout l'air d'être un CSV que tu essayes de parcourir.

    Pourquoi ne pas utiliser les fonctions php qui servent à ça (http://php.net//manual/fr/function.fgetcsv.php) pour faire ce que tu souhaites ?
    Un message utile vous a aidé ? N'oubliez pas le

    www.simplifions.fr - Simplifier vos comptes entre amis !

  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
    C'est en effet un fichier csv mais j'ai un problème de poids et d'encodage pour l'utilisé comme tel.
    C'est aussi afin de vérifier que le fichier est bien complet et correct.

    J'ai trouvé la regex suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #(\x0A.*)(\x0A)((?!((C|M|S);(M|S);)).*\x0A)#
    Mais je dois l'exécuté plusieurs fois pour que cela supprime tous les cas.
    edit : Si les lignes en erreurs se suivent, la seconde n'est pas prise en compte d'où l'obligation de l’exécuter une deuxième fois.
    " 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
    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
    Le plus simple est d'utiliser preg_split pour séparer chaque enregistrements.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $records = preg_split('/^(?=[ABC];[AB];)/m', $str, -1, PREG_SPLIT_NO_EMPTY);
    Il est ensuite facile d'isoler la dernière partie de chaque enregistrements pour effectuer un traitement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $records = array_map(function ($record) {
        $parts = explode(';', rtrim($record, "\n"), 3);
        // traitement que tu veux sur la dernière partie $parts[2]
        return implode(';', $parts);
    }, $records);
     
    $result = implode("\n", $records);

    Ou tu peux aussi utiliser preg_replace_callback:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $result = preg_replace_callback('~^([ABC];[AB];)((?:[^;]+;)*?)(?=\n(?1)|\z)~m', function ($m) {
        // la dernière partie se trouve dans $m[2];
        // traitement sur $m[2]
        return $m[2];
    }, $str);
    À noter que dans les deux approches, il est facile de n'effectuer un traitement que sur les enregistrements contenant un LF, en faisant un simple test dans la closure:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (strpos($m[2], "\n")!==false) { #...
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

Discussions similaires

  1. [RegEx] Regex pour preg_replace avec exclusion
    Par Aqua-Passion.com dans le forum Langage
    Réponses: 2
    Dernier message: 17/07/2011, 20h41
  2. REGEX avec exclusion des balises HTML
    Par Tchupacabra dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 15/10/2008, 09h21
  3. Utiliser un héritage avec exclusion mutuelle correctement
    Par akecoocoo dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 20/11/2005, 22h54
  4. [MySQL] select avec affichage conditionnel
    Par encoupe dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 31/10/2005, 23h46
  5. Problème de Regex ... avec un point
    Par bugalood dans le forum Langage
    Réponses: 2
    Dernier message: 29/05/2005, 10h26

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