Expression reguliere quote

Bonjour,

Bonjour,

je recherche a faire une expression reguliere avec preg_split sur des quotes

exemple :

mon texte 'entre quote' la suite

obtenir :
array ( 0 => "mon texte ", 1 => "'entre quote'", 2 => " la suite");

6 réponses

  1. Contributeur
    Salut maka54,

    Je pense que c'est plutôt preg_match que tu voudras utiliser.

    <?php     
    
    $str = "mon texte 'entre quote' la suite ";     
    
    preg_match("/^(.*)('.*')(.*)$/", $str, $matches);     
    
    print_r($matches);     
    
    ?>

    Tu peux aussi faire /^(.*)\s*('.*')\s*(.*)\s*$/ si tu ne veux pas capturer les espaces éventuels.

    Note que c'est une mauvaise idée d'utiliser ' comme délimiteur, dans la mesure où ce caractère risque de se retrouver dans du texte en langue française (ou en anglais ou d'autres langues).

    L'expression fonctionnera comme tu l'attends s'il n'y a pas plus de deux quotes dans la chaîne et si ces deux quotes sont bien de part et d'autre du texte que tu veux capturer.

    Autrement dit, par exemple, le paragraphe précédent matche bien l'expression, mais cela pourrait être le fruit du hasard, et on ne peut pas faire autrement à moins qu'il y ait d'autres règles de format de tes chaînes que tu ne nous ait pas communiquées.

    Tu devrais tester aussi la valeur de retour de preg_match, bien sûr.

    https://www.php.net/manual/fr/function.preg-match.php

    Dal
    1. bonjour,

      merci pour ta réponse et tes explications

      comme dis plus haut c'est bien preg_split que j'ai besoin

      et voici la regex que j'ai utilisé :

      /('[^']*')|("[^"]*")/isU


      elle fonctionne par contre comme tu dis, si il y a une quote utilisée, çà ne marche plus

      mon idée serait d'exclure la quote simple mais d'acceptée si elle est échappée par un antislashes

      tu aurais une idée de comment faire ?
      1. Contributeur
        Salut maka54,

        Tu dois savoir ce qui te convient, mais cette expression avec preg_split renvoie Array ( [0] => mon texte [1] => la suite ) et non pas array ( 0 => "mon texte ", 1 => "'entre quote'", 2 => " la suite"), ce qui était ta demande initiale.

        C'est en revanche ce que peut faire preg_match avec l'expression que j'ai proposée.

        Je ne comprend pas trop les options isU que tu as mises (en particulier i, car il n'y a rien dans ton expression qui soit concerné par la casse), et ton expression me semble aussi inutilement complexe.

        En ce qui concerne ton expression, si tu utilises preg_split, elle doit représenter ton délimiteur.

        Si, en fait, ce que tu veux récupérer est ce qui est avant une première quote et après une autre quote (qu'on va désormais supposer échappées), cela veut dire que l'expression doit matcher deux quotes échappées avec normalement du texte entre les deux (qu'il y ait des quotes non échappées dedans ou pas), et tu ne récupères pas ce qui est dans les quotes échappées, ni les quotes échappées elles-mêmes.

        Si c'est vraiment ce que tu veux, il suffit de construire ton expression en incluant l'antislash dans l'expression, en l'échappant lui même.

        Je ferai personnellement comme cela, sur :

        c'est un texte \'c'est entre quote\' ici, c'est la suite 

        on peut appliquer avec preg_split :
        /\\'.*\\'/sU

        (si les options sU te sont vraiment utile https://www.php.net/manual/fr/reference.pcre.pattern.modifiers.php)

        et cela donne :
        Array ( [0] => c'est un texte [1] => ici, c'est la suite ) 

        Mais plus d'un chemin mène à Rome :-)

        Dal
        1. Bonjour,

          Je suis pas un roi de la regex comme tu peux le voir nottamment vis à vis des options ...

          j'ai récup beaucoup d'exemple de regex des fois avec des fois sans ...

          -----------------------------------------------

          Voici mon code actuel :

          je récupère ce que j'attend avec cette expression :

          $matches = preg_split ( '/(\'[^\']*\')|("[^"]*")/isU', $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY  );   
          


          J'ai essayé ton code, malheureusement çà ne marche pas, puisque je ne récupère pas le texte entre quote

          ---------------------------------------------

          Et voilà ce que je cherche a faire exactement:
          $variable = 'c\'est entre quote';   
          

          Ce qui me donnerait :

          Array ( [0] => $variable = , [1] => 'c\'est entre quote', [2] => ; ) ;  


          Mon code fonctionne tant que le texte ne contient pas la meme quote qui l'entoure ...

          D'ou mon idée de gérer l'échappement et comme c'est moi qui écrit le texte, à moi d'échapper si besoin
          1. Contributeur
            J'ai essayé ton code, malheureusement çà ne marche pas, puisque je ne récupère pas le texte entre quote

            Bien sûr. Mais as-tu bien lu ce que j'ai écrit ?

            Et voilà ce que je cherche a faire exactement:

            $variable = 'c\'est entre quote';

            Ce qui me donnerait :

            Array ( [0] => $variable = , [1] => 'c\'est entre quote', [2] => ; ) ;


            C'est encore quelque chose de différent par rapport à ta demande initiale et à ton message précédent. C'est, en fait, complètement différent, et vraiment pas clair. Dans ton exemple de ce que tu dis chercher "exactement" à faire, il n'y a rien "entre quote" dans la chaîne de départ et dans le résultat que tu attends, il n'y a rien d'utile, à mon sens, voire des choses impossibles (le ; n'est nulle part dans la chaîne).

            Réécrit clairement tes cas d'application, s'il te plaît.

            Dal
          2. Alors, j'ai peut-être pas été clair avec l'exemple :

            la chaine de caractères , c'est :
            $variable = 'c\'est entre quote';

            Et ce n'est pas un bout de code, mais bien la chaine complète .

            Mais le texte avant et après pourrait être n'importe quoi d'autre
        2. Je ne cherche pas a formater une chaine en particulier mais n'importe quel cas de figure, donc c'est normal que le point virgule n'y figure pas

          je veux découper ma chaine, puis je traite chaque information recues indépendamment des autres, mon but n'étant pas de supprimer des morceaux de chaines mais de les découper

          je viens de trouver la regex qu'il me faut :

          /('(?:\\.|[^\'])*?')|("(?:\\.|[^\\"])*?")/sU


          avec c'est regex çà fonctionne impec, que ce soit simple ou double quote

          voilà le code que j'utilise :

          $quote_regexp = array( 
          		'simple_quote' 	=> '(\'(?:\\\.|[^\\\'])*?\')',
          		'double_quote'  => '("(?:\\\.|[^\\\"])*?")'
          	);
          $quote_regexp = "/" . join( "|", $quote_regexp ) . "/sU";
          
          $split = preg_split ( $quote_regexp, $text, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY  );
          
          while( $chaines = array_shift( $split ) ){
          
          	...
          
          }
          1. Contributeur
            :-/

            Mets ceci devant ce code :

            $st1 = "c'est un texte \\'c'est entre quote\\' ici, c'est la suite";
            $st2 = "un texte \\'entre quote\\' ici la suite";
            $st3 = 'un texte "entre quote" ici la suite';
            $st4 = 'c\'est un texte "c\'est entre quote" ici, c\'est la suite';
            
            $text = $st1;
            
            echo "<p>On splitte ceci :</p>";
            echo "<pre>$text</pre>";

            et teste successivement $text avec les valeurs de $st1, $st2, $st3 et $st4.

            Dal
          2. Contributeur
            Cela donne successivement :

            $st1:
            On splitte ceci :
            
            c'est un texte \'c'est entre quote\' ici, c'est la suite
            
            chaines = c
            chaines = 'est un texte \'c'
            chaines = est entre quote\
            chaines = ' ici, c'
            chaines = est la suite 

            $st2:
            On splitte ceci :
            
            un texte \'entre quote\' ici la suite
            
            chaines = un texte \
            chaines = 'entre quote\'
            chaines = ici la suite 

            $st3:
            On splitte ceci :
            
            un texte "entre quote" ici la suite
            
            chaines = un texte
            chaines = "entre quote"
            chaines = ici la suite 

            $st4:
            On splitte ceci :
            
            c'est un texte "c'est entre quote" ici, c'est la suite
            
            chaines = c
            chaines = 'est un texte "c'
            chaines = est entre quote" ici, c'est la suite 

            Si c'est vraiment ce que tu cherches à faire, alors bravo.

            Mais, j'ai comme un doute :-)

            Dal
          3. Voilà ce que j'obtiens ;

            Exactement ce que je cherche:

            Array
            (
                [0] => 
            $st1 = 
                [1] => "c'est un texte \\'c'est entre quote\\' ici, c'est la suite"
                [2] => ;
            $st2 = 
                [3] => "un texte \\'entre quote\\' ici la suite"
                [4] => ;
            $st3 = 
                [5] => 'un texte "entre quote" ici la suite'
                [6] => ;
            $st4 = 
                [7] => 'c\'est un texte "c\'est entre quote" ici, c\'est la suite'
                [8] => ;
            
            )


            pour moi $st1 ... $st4 ne sont pas des variables mais font partie du texte

            ma chaine à spliter est l'ensemble des 4 lignes
          4. Contributeur
            maka54 a écrit le 6 sept. 2012 à 11:57:

            exemple :

            mon texte 'entre quote' la suite

            obtenir :

            array ( 0 => "mon texte ", 1 => "'entre quote'", 2 => " la suite");


            Cherche l'erreur :-(

            Dal
          5. l'erreur est peut etre d'avoir ajouté des quotes au valeurs du tableau, du coup çà embrouille un peu ...

            l'exemple du dessus est un copié collé d'un print_r() donc pas de quote

            mais sinon il n'y a pas d'erreur
        3. Contributeur
          Salut maka54,

          Avec preg_match, en échappant ' s'il doit l'être dans la chaîne recherchée pour ne pas le confondre avec l'apostrophe pouvant être utilisée par ailleurs, en utilisant " alternativement, et en capturant tout, y compris ce qui est entre \' ou " et en l'éclatant dans un tableau :

          <?php 
          
          $st1 = "c'est un texte \\'c'est entre quote\\' ici, c'est la suite"; 
          $st2 = "un texte \\'entre quote\\' ici la suite"; 
          $st3 = 'un texte "entre quote" ici la suite'; 
          $st4 = 'c\'est un texte "c\'est entre quote" ici, c\'est la suite'; 
          
          $text = $st4; 
          
          echo "<p>On splitte ceci :</p>"; 
          echo "<pre>$text</pre>"; 
          
          if ( preg_match("/^(.*)(\\\'.*\\\'|\".*\")(.*)$/", $text, $matches) ) 
          { 
            echo "<p>Avec preg_match :</p>"; 
            array_shift($matches); 
            while( $chaines = array_shift( $matches) ){ 
              echo "chaines = $chaines <br />"; 
            } 
          } else { 
            echo "<p>Erreur : la chaîne testée ne correspond pas au masque recherché</p>"; 
          }

          En testant successivement $text avec les valeurs de $st1, $st2, $st3 et $st4, on a :

          $st1:
          On splitte ceci : 
          
          c'est un texte \'c'est entre quote\' ici, c'est la suite 
          
          Avec preg_match : 
          chaines = c'est un texte 
          chaines = \'c'est entre quote\' 
          chaines = ici, c'est la suite

          $st2:
          On splitte ceci : 
          
          un texte \'entre quote\' ici la suite 
          
          Avec preg_match : 
          chaines = un texte 
          chaines = \'entre quote\' 
          chaines = ici la suite 

          $st3:
          On splitte ceci : 
          
          un texte "entre quote" ici la suite 
          
          Avec preg_match : 
          chaines = un texte 
          chaines = "entre quote" 
          chaines = ici la suite 

          $st4:
          On splitte ceci : 
          
          c'est un texte "c'est entre quote" ici, c'est la suite 
          
          Avec preg_match : 
          chaines = c'est un texte 
          chaines = "c'est entre quote" 
          chaines = ici, c'est la suite 

          N'est-ce pas cela que tu veux faire ?

          Dal
          1. Non dans l'exemple $st1

            Voilà ce que je veux

            chaines = $st1 =
            chaines = "c'est un texte \\'c'est entre quote\\' ici, c'est la suite"
            chaines = ;

            Donc dans cet exemple un simple quote ne me dérange pas, mais une double échappée si car elle coupait ma chaine d'ou mon idée de regex qui annule un échappement