regexe simple (avec ! et \)

Eléphanteau du PHP | 34 Messages

13 août 2016, 20:18

Salut tout le monde,
j'ai un problème avec une regexe toute bête :
"/(!\\\\)[!eE]/"
J'aimerais signifier prendre les caractères ! e et E sauf quand il y a un antislash (\) devant.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

14 août 2016, 14:25

Bonjour,

Voici un outil très pratique pour développer/tester ses regex :
http://www.regex101.com

Pour ta demande, tu auras probablement besoin de mettre [^\\] pour indiquer n'importe quel caractère sauf l'antislash
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

14 août 2016, 14:56

j'avais penser à ça aussi mais non parce-que sinon il prend un caractères en trop si j'écrit 'zesrg3e. ' il prend '3e.' et non 'e.' tout simplement. Moi je ne veux pas dire tout sauf antislash mais PRÉCÉDER de tout sauf antislash. J'ai penser à ça : /(?<!\\\\)[!eE]\./ mais ça ne marche pas non plus...

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

14 août 2016, 15:06

Il ne prend pas de caractère en trop si tu mets des parenthèses capturantes correctement ;)
https://regex101.com/r/oL3oW9/1
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

14 août 2016, 19:26

ton code fonctionne sur la simulation tout comme (?<!\\)([!eE]\.) mais dans mon code ça ne marche plus :

Code : Tout sélectionner

if(preg_match_all("/[^\\]([eE!])\./",$math,$match_math)) { foreach ($match_math as $v1_math) { foreach ($v1_math as $c_math=>$v2_math) { $replacement_math = "<font color='purple'>".$v2_math."</font>"; $math = str_replace($v2_math, $replacement_math, $math); } } }

Mammouth du PHP | 2703 Messages

14 août 2016, 19:29

tu as ajouté \.
sur quelle chaine fais-tu le test ?

Eléphanteau du PHP | 34 Messages

14 août 2016, 19:35

!. \!. e. \e. E. \E.
Ne t'inquiète pas j'ai bien rajouter le point dans ma chaîne de teste :wink:

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

15 août 2016, 13:56

Pars d'un code basique :
$chaine_de_test="ta chaine de test";
preg_match_all(...);
var_dump($matches);

Qu'est ce que ça donne ?
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

15 août 2016, 16:39

Si je fait ça :

Code : Tout sélectionner

$chaine_de_test="!. \!. e. \e. E. \E."; preg_match_all("/[eE!]\./",$chaine_de_test,$matches); $math = var_dump($matches);
ça donne ce truc immonde :
array(1) { [0]=> array(5) { [0]=> string(2) "!." [1]=> string(2) "!." [2]=> string(2) "e." [3]=> string(2) "E." [4]=> string(2) "E." } } array(1) { [0]=> array(5) { [0]=> string(2) "!." [1]=> string(2) "!." [2]=> string(2) "e." [3]=> string(2) "E." [4]=> string(2) "E." } } array(1) { [0]=> array(5) { [0]=> string(2) "!." [1]=> string(2) "!." [2]=> string(2) "e." [3]=> string(2) "E." [4]=> string(2) "E." } } array(1) { [0]=> array(5) { [0]=> string(2) "!." [1]=> string(2) "!." [2]=> string(2) "e." [3]=> string(2) "E." [4]=> string(2) "E." } }

Si je fait ça (qui marche en partie sur le site de simulation) :

Code : Tout sélectionner

$chaine_de_test="!. \!. e. \e. E. \E."; preg_match_all("/[^\\]([eE!]\.)/",$chaine_de_test,$matches); $math = var_dump($matches);
j'obtiens:
NULL NULL NULL NULL

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

15 août 2016, 17:33

Effectivement, c'est un peu plus tordu que prévu :
$chaine_de_test='!. \!. e. \e. E. \E.';
preg_match_all("/(?:^|[^\\\])([!eE]\.)/",$chaine_de_test,$matches);
$math = var_dump($matches);
qui donne :

Code : Tout sélectionner

array (size=2) 0 => array (size=3) 0 => string '!.' (length=2) 1 => string ' e.' (length=3) 2 => string ' E.' (length=3) 1 => array (size=3) 0 => string '!.' (length=2) 1 => string 'e.' (length=2) 2 => string 'E.' (length=2)
Dans $math[0] tu as le tableau des éléments correspondant à l'ensemble de ton motif (donc avec les espaces avant).
Dans $math[1] tu as le tableau des éléments correspondant uniquement à tes parenthèses capturantes (donc c'est ce qui t'intéresse)
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

16 août 2016, 14:56

J'ai toujours un problème de sélection d’espace en trop...

Code : Tout sélectionner

if(preg_match_all("/(?:^|[^\\\])([!eE]\.)/",$math,$match_math)) { foreach ($match_math[0] as $v1_math) { $replacement_math = "<font color='purple'>".$v1_math."</font>"; $math = str_replace($v1_math, $replacement_math, $math); $replacement_math = str_replace(".", "", $v1_math); $math = str_replace($v1_math, $replacement_math, $math); } }

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

16 août 2016, 21:12

Relis mon message ;-)
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

17 août 2016, 12:52

oui mais si je remplace $match_math[0] par $match_math[1], il capture y compris quand il y a un \ devant.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 9782 Messages

17 août 2016, 19:07

Fait un var_dump de $match_math et tu verras que non
Quand tout le reste a échoué, lisez le mode d'emploi...

Eléphanteau du PHP | 34 Messages

17 août 2016, 19:42

Si je fait var_dump de match_math j'ai trois sous-array :
- le premier (0) sélectionne ce qu'il faut mes des caractères en trop aussi :
array(3) { [0]=> string(3) ">E." [1]=> string(3) ">e." [2]=> string(3) " e." } array(3) { [0]=> string(3) " !." [1]=> string(3) " e." [2]=> string(3) " E." } array(3) { [0]=> string(3) ">E." [1]=> string(3) ">e." [2]=> string(3) " e." } array(3) { [0]=> string(3) " !." [1]=> string(3) " e." [2]=> string(3) " E." }
Pourquoi y a t-il ceci qui est compris "<" dans ">E." ?
- le second sélectionne uniquement les bons caractère mais le fait aussi quand il y a un antislash (qui lui n'est pas pris) :
array(3) { [0]=> string(2) "E." [1]=> string(2) "e." [2]=> string(2) "e." } array(3) { [0]=> string(2) "!." [1]=> string(2) "e." [2]=> string(2) "E." } array(3) { [0]=> string(2) "E." [1]=> string(2) "e." [2]=> string(2) "e." } array(3) { [0]=> string(2) "!." [1]=> string(2) "e." [2]=> string(2) "E." }
- le troisième ne sélectionne rien :
NULL NULL NULL NULL