Expression reguliere quote [Fermé]

Signaler
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
-
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
-
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

Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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 ?
Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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
Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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 ) ){

	...

}
Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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
Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
<?php 
ob_start(); 

?> 
$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'; 
un exemple sans échappement : ce que je ne veux pas 
$st5 = 'c'est un texte "c'est entre quote" ici, c'est la suite'; 
<?php 

$text = ob_get_contents(); 

$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  ); 

print_r($split); 


?>



j'ai mis le texte brut en cache avec ob pour ne pas avoir de souci de quote avec php

et le résultat :

$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';
un exemple sans échappement : ce que je ne veux pas
$st5 = 'c'est un texte "c'est entre quote" ici, c'est la suite';
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] => ;
un exemple sans échappement : ce que je ne veux pas
$st5 = 
    [9] => 'c'
    [10] => est un texte 
    [11] => "c'est entre quote"
    [12] =>  ici, c
    [13] => 'est la suite'
    [14] => ;

)


Il y a un souci avec la $st5 sans les échappement, la phrase en saccadée
Messages postés
5333
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
7 mai 2020
875
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
Messages postés
699
Date d'inscription
mercredi 8 avril 2009
Statut
Membre
Dernière intervention
4 décembre 2016
78
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