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 :

trouver mot entre guillemet


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 173
    Points : 88
    Points
    88
    Par défaut trouver mot entre guillemet
    Hello,

    je cherche à trouver des mots entre guillemet en évitant les mots collé entre eux.
    du coup je controle les espace entre chaque mot et la c'est le drame :

    (?:^|\s)(["]([^\"]*)["])(?:$|\s)
    "jjj" "jjj" "jjj"

    il m'en rate un au centre.

    comment corrigé cela ?

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Je suis pas sûr mais essaye ceci :
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 173
    Points : 88
    Points
    88
    Par défaut
    merci pour la reponse , mais malheureusement, les mot collé entre eux sont reconnu comme bon, alors que je souhaite qu'il soit rejeté ;


    voila ce que je souhaite :

    "jjj" "jjjjj" "jjjj"

    "jjjj" "jjjj" "jjjj"

    "jjj""jjjj" "jjjj"

    "jjj"jjj"jjj"

    en vous remerciant

  4. #4
    Expert éminent sénior
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 234
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 234
    Points : 15 531
    Points
    15 531
    Par défaut
    tu peux tester ça sans passer par un expression régulière :

    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
    $texte = '"jjj1" "jjjjj2" "jjjj3" "jjjj4 ""jjjj5" "jj6" "jjj7""jjjj8" "jjjj9" "jjj10"jjj11"jjj12"';
     
    $guillemet = '"';
     
    foreach (explode(" ", $texte) as $element) {
        $interieur = trim($element, $guillemet);
     
        if (   ("$guillemet$interieur$guillemet" === $element)
            && (FALSE === strpos($interieur, $guillemet))
        ) {
            echo "<strong>$interieur</strong> correspond<br/>\n";
        } else {
            echo "$element ne correspond pas<br/>\n";
        }
    }

  5. #5
    Membre actif Avatar de Chen norris
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 216
    Points : 248
    Points
    248
    Par défaut
    Testé sur un site que j'aime beaucoup : (le site en question : http://regexper.com)
    En espérant que ça réponde à ta problématique… (car pas sûr d'avoir parfaitement compris la demande)

    Version de regexp qui prend en compte l'obligation d'avoir au moins un espace entre chaque mot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ^((("){1}([^"])*("){1})([ ]+))+$
    Enfin, dernière version où on teste "avoir un mot, éventuellement suivi d'autres mots avec obligation d'au moins un espace entre chaque mot" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ^(("){1}([^"])*("){1})(([ ]+)(("){1}([^"])*("){1}))*$
    J'ai testé cette dernière version sur ce site : http://www.annuaire-info.com/outil-r...ion-reguliere/ et j'ai comme résultats :
    • "jjjj" → VRAI
    • "jj"jj" → FAUX
    • "jj""jjj" → FAUX
    • "jj" "jjjjj" → VRAI
    Chen norris
    C/C++, C#, Java, PHP & SQL coder
    Web developer

  6. #6
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Je crois que j'ai un truc qui marche avec les lookahead et lookbehind
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?:^|(?<=\s))"([^"]+)"(?:$|(?=\s))
    En quelques mots :
    • (?:^|(?<=\s)) : si on n'est pas au début de la chaîne, on vérifie qu'il y a une espace avant le début de la correspondance ;
    • "([^"]+)" : la partie « normale » du pattern, j'ai rajouté des parenthèses pour capturer le contenu des guillemets ;
    • (?:$|(?=\s)) : si on n'est pas à la fin de la chaîne, on vérifie qu'il y a une espace après la fin de la correspondance.

    Exemple avec ce script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?php
    header('Content-Type: text/html; charset=utf-8');
     
    $pattern = '/(?:^|(?<=\s))"([^"]+)"(?:$|(?=\s))/';
    $subject = '"bavoir" "salon""potiron" "magique" "élément"xavier "salut"';
    preg_match_all($pattern, $subject, $matches);
     
    echo '<pre>';
    echo "$subject\n";
    print_r($matches);
    echo '</pre>';
    ?>
    J'obtiens :
    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
    "bavoir" "salon""potiron" "magique" "élément"xavier "salut"
    Array
    (
        [0] => Array
            (
                [0] => "bavoir"
                [1] => "magique"
                [2] => "salut"
            )
     
        [1] => Array
            (
                [0] => bavoir
                [1] => magique
                [2] => salut
            )
     
    )
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  7. #7
    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
    Pour résoudre le problème il faut effectivement recourir aux tests avant et arrière (lookahead, lookbehind) pour contrôler que la partie entre guillemets est bien entourée soit de caractères blancs, soit des limites de la chaîne, donc:Mais ce n'est pas suffisant, car par exemple avec une chaîne comme "abc""def "ghi" jkl" la pattern va réussir avec "ghi" bien que cette partie soit hors des guillemets (les guillemets ici sont respectivement le guillemet fermant de "def " et le guillemet ouvrant de " jkl")

    principe:

    La solution pour ne pas se décaler dans les guillemets consiste à décrire systématiquement dans la pattern toutes les parties entre guillemets qu'elles soient conforme (entourées d'espaces) ou pas. La manière la plus basique consiste à créer un groupe de capture pour pouvoir différencier les deux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (?<!\S)("[^"]*")(?!\S)|"[^"]*"
    Donc si le groupe de capture existe, c'est qu'il s'agit de la partie conforme, dans le cas contraire c'est une partie à éviter.

    optimisation:

    Une pattern basée sur une alternative n'est jamais bien performante, car le moteur de regex va devoir tester chaque caractère de la chaîne deux fois (une fois par branche) pour enfin se rendre compte qu'il ne s'agit pas d'un guillemet et passer au suivant.

    Pour éviter cette lenteur, on va mettre le guillemet ouvrant en facteur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "(?:(?<!\S.)([^"]*")(?!\S)|[^"]*")
    Cette manœuvre permet de profiter d'une pré-optimisation qui recherche à l'avance les positions dans la chaîne où la pattern peut réussir en se basant sur les chaînes littérales de la pattern (le guillemet ouvrant dans ce cas). Concrètement, dans la chaîne "abc" xxxxxxxxx "def" la pattern ne sera même pas testée aux positions marquées par un x, elles sont exclues d'emblée dés cette pré-optimisation (la version précédente aurait dû tester chaque x deux fois).

    Le coup du groupe de capture c'est bien gentil, mais une fois qu'on a les résultats, on est obligé de faire un test pour savoir à quoi on a à faire. On peut l'éviter en faisant échouer la pattern et en demandant au moteur de regex de sauter les caractères qu'il a déjà trouvés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "(?:(?<!\S.)[^"]*"(*SKIP)(?!\S)|[^"]*"(*SKIP)(*F))
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Membre actif Avatar de Chen norris
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 216
    Points : 248
    Points
    248
    Par défaut
    Petite question, CosmoKnacki : dans tes regexp, à quoi correspond le "<" au début ? J'ai cherché mais je n'ai pas trouvé…
    Chen norris
    C/C++, C#, Java, PHP & SQL coder
    Web developer

  9. #9
    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 < est un morceau du test arrière négatif (negative lookbehind) dont la syntaxe est (?<!...) (non précédé de ...).

    Sinon un < pris isolément n'a pas de sens particulier, c'est juste un <.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  10. #10
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Le terme savant c'est « assertion arrière négative », en anglais lookbehind. C'est difficile de trouver une doc qui explique ça vraiment clairement, et à plus forte raison une doc en français. Voilà ce que j'ai trouvé :
    FR : http://www.expreg.com/assertion2.php
    EN : http://www.regular-expressions.info/lookaround.html
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  11. #11
    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
    Tu le trouves dans le tutoriel de Guillaume Rossolini: http://g-rossolini.developpez.com/tu...=syntaxe#LII-8
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

Discussions similaires

  1. [RegEx] Extraire mot entre guillemets
    Par mxh77 dans le forum Langage
    Réponses: 5
    Dernier message: 12/06/2014, 19h48
  2. [Regex] Trouver les mots entre certains autres mots
    Par lequebecois79 dans le forum Langage
    Réponses: 0
    Dernier message: 13/02/2012, 20h57
  3. Mettre mot entre guillemets en AWK ?
    Par Moostiq dans le forum Shell et commandes GNU
    Réponses: 11
    Dernier message: 18/10/2011, 16h16
  4. [RegEx] Trouver les mots entre guillemets
    Par naynay dans le forum Langage
    Réponses: 6
    Dernier message: 20/07/2009, 16h43
  5. [RegEx] Trouver certains mots entre [] dans une chaine de caractères
    Par Prosis dans le forum Langage
    Réponses: 3
    Dernier message: 22/10/2007, 21h52

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