PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 24-02-2011 10:05:20

Pierrot
Ancien nouveau
Inscription : 08-05-2009
Messages : 1 195

Y a un roi des RegExp ici ?

Salut la compagnie big_smile

j'ai un probleme, je crois bien que ...............

heu non, pas celui là big_smile:D


j'ai une chaine :
"skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* hfhfhf */  jsdqjlkd jqklsjd qskl jsdq /* kikiki */ skj dqskljd "

je veut virer tout ce qui est entre ca '/*' et ca '*/' ces caractères compris .

resultat :

"skdlj sdlkfjsl  hqsd qksjdhqskjhdk   jsdqjlkd jqklsjd qskl jsdq  skj dqskljd "

un gros bizou à celui qui me trouve la RexExp magique big_smile:D


a++

Hors ligne

#2 24-02-2011 12:19:41

xTG
GrandGourou
Inscription : 18-06-2009
Messages : 1 127
Site Web

Re : Y a un roi des RegExp ici ?

A vue de nez :

$chaine = preg_replace("#^(.*)(\/\*)(.*)(\*\/)(.*)$#","$1$3",$chaine);

(pas essayée)

Sinon Moogli avait posté sur phpFrance il me semble un lien vers un générateur d'expression régulière, mais je l'ai pas retrouvé dans mes favoris...

Dernière modification par xTG (24-02-2011 12:20:04)

Hors ligne

#3 24-02-2011 12:46:24

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Bonjour,

Désolé xTG, mais ton motif ne matche pas.
Par contre essaye avec celui-ci :


$chaine=preg_replace("#[\/\*]*(\w\s*)[\*\/*]*#","$1$3",$chaine);
 

qui devrait marcher. Par contre si ta chaine commence par "/* blabla */" ta sortie devrait garder le premier "/*", et pour ca je te laisse continuer^^ histoire de ne pas avoir de bisous wink

EDIT: le motif suivant : "#[\/\*]*([\w|\s]*)[\*\/*]*#" est mieux mais ne résoud pas le soucis énnoncé précedemment^^

Dernière modification par Jc (24-02-2011 12:50:31)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#4 24-02-2011 12:52:57

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Je ne suis vraiment pas fort en regexp, mais la tienne non plus ne fonctionne pas Jc, le contenu du premier commentaire ne saute pas  /* 111*/, les 111 ne sont pas supprimés.
Et souci ne prend pas de s, au singulier


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#5 24-02-2011 13:01:51

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

C'est le problème que j'avais ennoncé, si la chaîne commence par un commentaire ça ne marche plus.
Mais pour te faire plaisir essaye comme ça


$chaine=preg_replace("#([\w|\s]*)[?<=\/\*]*([\w|\s]*)[?=\*\/]*#","$1",$chaine);
 

désolé, mais j'ai plein de soucis wink

Dernière modification par Jc (24-02-2011 14:15:58)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#6 24-02-2011 13:33:05

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Alors là, il n'y a pas de souci.
Sauf pour moi, pour essayer de comprendre cet ésotérisme de la twilight zone.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#7 24-02-2011 13:49:12

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Ce qui ne me semble pas documenté :
?<= et ?=
Pour le reste je comprends


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#8 24-02-2011 13:51:39

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Re Bonjour,

Alors pendant mon repas, ça a trotté encore un peu dans ma tête malgré moi, et voila en beaucoup plus simple et plus rapide :


$result=preg_match_all("#[?<!\/\*]*([\w|\s]*)[?!\*\/]*#",$chaine,$matches)
 

faut juste reconstituer le resultat à partir de $matches.

Bonne journée à vous et j'espère que MK n'aura pas trop mal à la tête^^

Dernière modification par Jc (24-02-2011 14:15:41)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#9 24-02-2011 13:56:06

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Bon là tu inverses la problématique. J'étais moi-même plutôt parti sur preg_match_all avec le caractère ! pour faire des masques d'exclusions.
Mais je ne connais pas la fonction du caractère < entre le ? et le !, comme avant avec ?<= et ?=


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#10 24-02-2011 14:15:26

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Voila pour toi MK, ça me fait plaisir smile

Alors en fait ce sont des assertions simples.
Pour t'expliquer le preg_match_all, je vais partir de la capture du motif (pattern) à savoir ([\w|\s]*)
\w : tout caractère de "mot" [A-Za-z0-9_] plus les accentués
| : ou inclusif
\s : tout caractère blanc
* : autant qu'il y en a
A ce stade toute la chaîne est capturée sauf les "/*" et "*/"
Grâce aux assertions simples on va vérifier que ce qui se trouve avant ce pattern (ensemble des conditions ci-dessus) ?<!  ne vérifie pas la condition suivante : présence des caractères "/*". Comme ce sont des caractères spéciaux, il faut les echapper avec un "\" d'où : "\/\*"
Ensuite, après le pattern on fait de même avec une assertion avant négative avec ?! et "*/" qui doit s'écrire de même "\*\/"
les étoiles après les assertions servent à continuer a rechercher dans le reste de la chaîne.

Dernière modification par Jc (24-02-2011 14:17:09)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#11 24-02-2011 14:22:06

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Pour expliquer le preg_replace, j'ai fait l'inverse, à savoir utiliser les assertions positives en pattern $2 et les autres en $1 et j'ai remplacé le contenu que par les $1 puisque les $2 on en veut pas et que \w ne capture pas /* et */


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#12 24-02-2011 14:24:34

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Je viens juste de trouver ça

Types d'assertion    Motif    Succès si le motif dans l'assertion...

  Les assertions arrières positives (positive lookbehind)    (?<=motif)    ...trouve une concordance à gauche

  Les assertions arrières négatives (negative lookbehind)    (?<!motif)    ...ne trouve pas de concordance à gauche

  Les assertions avant positives (positive lookahead)    (?=motif)    ...trouve une concordance à droite

  Les assertions avant négatives (negative lookahead)    (?!motif)    ...ne trouve pas de concordance à droite

Vivement la retraite que je prenne, enfin, le temps de me pencher sur ces p**** de regex !


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#13 24-02-2011 14:29:07

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

^^

Vu le mal qu'on s'est donné j'espère que notre ami pierrot nous dira si le preg_replace est plus rapide que le preg_match_all + reconstruction de la chaîne.

Ne croit pas que t'allais t'en tirer avec un simple bisou big_smile


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#14 24-02-2011 14:47:28

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Bon alors, je récapitule :

<?php
$source ="skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* hfhfhf */  jsdqjlkd jqklsjd qskl jsdq /* kikiki */ skj dqskljd ";
echo '<pre>';
$result=preg_match_all("#[?<!\/\*]*([\w|\s]*)[?!\*\/]*#",$source,$matches);
print_r($matches);
echo '</pre>';
echo implode($matches[1],' ');
/*
[?<!\/\*]* assertion arrière négative tout ce qui, à gauche de * ne coresspond pas à /*
([\w|\s]*) pour capturer le reste mots ou espaces
[?!\*\/]* assertion avant négative tout ce qui à droite de * ne correspond pas à */

Sauf que à l'exécution:

Array
(
    [0] => Array
        (
            [0] => skdlj sdlkfjsl /*
            [1] =>  111*/
            [2] =>  hqsd qksjdhqskjhdk /*
            [3] =>  hfhfhf */
            [4] =>   jsdqjlkd jqklsjd qskl jsdq /*
            [5] =>  kikiki */
            [6] =>  skj dqskljd
            [7] =>
        )

    [1] => Array
        (
            [0] => skdlj sdlkfjsl
            [1] =>  111
            [2] =>  hqsd qksjdhqskjhdk
            [3] =>  hfhfhf
            [4] =>   jsdqjlkd jqklsjd qskl jsdq
            [5] =>  kikiki
            [6] =>  skj dqskljd
            [7] =>
        )

)

skdlj sdlkfjsl 111 hqsd qksjdhqskjhdk hfhfhf jsdqjlkd jqklsjd qskl jsdq kikiki skj dqskljd

Y-a un souci lol
Ou alors il faut sauter tous les index impairs de $matches[1]


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#15 24-02-2011 16:19:53

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Re bonjour,

J'avoue humblement que pour la version preg_match_all je me suis fait avoir, mais ca devrait passer avec


$motif="#(?<=[\/])([\w|\s]*)*(?=[\/\*|\w]*)#m";
 

Pas eu le temps de test si ca marche dans tous les cas de figure


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#16 24-02-2011 16:32:21

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

sinon celui-ci devrait couvrir plus de cas de figure


$motif="#^(\w|\s)+(?=[\/\*])|(?<=[\/])([\w|\s]*)*(?=[\/\*|\w]*)#m";
 

A utiliser toujours avec un preg_match_all

Dernière modification par Jc (24-02-2011 16:35:57)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#17 24-02-2011 17:03:35

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Va falloir qu'on commente pour les neu-neus, comme moi.
Je regarderai ça tout à l'heure à la maison.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#18 24-02-2011 18:45:41

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

Je suis dessus

<?php
$source ="skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* hfhfhf */  jsdqjlkd jqklsjd qskl jsdq /* kikiki */ skj dqskljd ";
$motif="#^(\w|\s)+(?=[\/\*])|(?<=[\/])([\w|\s]*)*(?=[\/\*|\w]*)#m";
echo '<pre>';
$result=preg_match_all($motif,$source,$matches);
array_pop($matches);array_pop($matches);
print_r($matches);
echo '</pre>';
echo implode($matches[0],' ');

Resultat

Array
(
    [0] => Array
        (
            [0] => skdlj sdlkfjsl
            [1] =>
            [2] =>  hqsd qksjdhqskjhdk
            [3] =>
            [4] =>   jsdqjlkd jqklsjd qskl jsdq
            [5] =>
            [6] =>  skj dqskljd
        )

)

skdlj sdlkfjsl hqsd qksjdhqskjhdk jsdqjlkd jqklsjd qskl jsdq skj dqskljd

Donc ça semble le faire.
Je vais donc maintenant essayé d'expliquer (donc de comprendre) $motif.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#19 24-02-2011 19:05:24

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

$motif="#^(\w|\s)+(?=[\/\*])|(?<=[\/])([\w|\s]*)*(?=[\/\*|\w]*)#m";
 

Décomposons pour nous autres les neu-neus :
Tout d'abord les # # sont les délimiteurs du motif.
le m final c'est l'option multi-lignes (ça ne mange effectivement pas de pain)

Premier bloc : ^(\w|\s)+ on cherche immédiatement au début de la chaîne (ligne ?) au moins un mot ou un espace
Deuxième bloc, alternatif :(?=[\/\*])|(?<=[\/])([\w|\s]*), celui là il faut le décomposer
il y a d'abord une assertion avant positive, on doit trouver sur la droite : /*, ce qui, échappé donne [\/\*]
on a ensuite la conjonction OU: | pour le côté alternatif
puis une assertion arrière positive : ?<=, on doit trouver à gauche /, ce qui, échappé donne \/
suivi de mots ou d'espaces ([\w|\s]*) en nombre 0 à n
Troisième bloc : * là j'avoue que je cale
Quatrième et dernier bloc : (?=[\/\*|\w]*) à nouveau une assertion avant positive, on doit trouver sur la droite un / suivi d'un ou plusieurs mots ou d'espaces ou de rien.

Maintenant, comment cela opère, mystère !


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

#20 24-02-2011 19:47:44

mcAllan
Mowdérateur
Lieu : Châteaurenard en Provence
Inscription : 08-05-2009
Messages : 269

Re : Y a un roi des RegExp ici ?

Bonsoir,

En passant rapidement, un simple :

[code php]
$result = preg_replace('`(\/\*.*\*\/)`Uis', '', $source);
[/code]

Je pense que cela fonctionne.

A+


Promotion de PPOO : Programmation Propre Orientée Objet !!
Recommande AAO : Apéritif Avec Olives...
Glop, glop

Hors ligne

#21 24-02-2011 20:15:08

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Bonjour

@McAllan : Dans la chaîne ex:


$texte="A skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* 222 */  jsdqjlkd jqklsjd qskl jsdq /* 444 */ skj dqskljd X";
 

ton code ne retourne que les parties suivantes:
A skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* 222 */  jsdqjlkd jqklsjd qskl jsdq /* 444 */ skj dqskljd X

EDIT: Je retire ce que je viens de dire, je viens de retest, j'avais fait une erreur et ton pattern matche^^ donc chapeau McAllan. Je n'y avait pas pensé comme cela, et c'est pourtant plus simple.

@mk: il y a deux parties à ma regex : 1) celle à gauche du | et la 2) à droite du |
Dans mon exemple ci-dessus, la 1) sert à recup : A skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* 222 */  jsdqjlkd jqklsjd qskl jsdq /* 444 */ skj dqskljd X
En effet la première assertion avant sert à arréter la capture du début de chaîne à la première /*
la 2e sert à récup le reste :  "A skdlj sdlkfjsl /* 111*/ hqsd qksjdhqskjhdk /* 222 */  jsdqjlkd jqklsjd qskl jsdq /* 444 */ skj dqskljd X". Pourquoi 2 parties? Parce la deuxième matche toutes les chaines encadrées (mode exclusif) par */ et /* avec une vérification pour la chaîne de fin qui elle n'est pas encadrée à droite. Celle du début n'étant pas encadrée à gauche.

Dernière modification par Jc (24-02-2011 20:35:00)


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#22 24-02-2011 20:31:32

mcAllan
Mowdérateur
Lieu : Châteaurenard en Provence
Inscription : 08-05-2009
Messages : 269

Re : Y a un roi des RegExp ici ?

Glop,

Ah bon... smile


Promotion de PPOO : Programmation Propre Orientée Objet !!
Recommande AAO : Apéritif Avec Olives...
Glop, glop

Hors ligne

#23 24-02-2011 20:39:43

Jc
Membre
Lieu : Zillisheim - Alsace
Inscription : 15-04-2010
Messages : 1 629
Site Web

Re : Y a un roi des RegExp ici ?

Oui, moi qui me targue de toujours aller au plus simple, je ne pourrais plus le dire, c'est en effet tellement plus simple de matcher un motif constant que l'inverse... sans commentaire et c'est plus court que

$chaine=preg_replace("#([\w|\s]*)[?<=\/\*]*([\w|\s]*)[?=\*\/]*#","$1",$chaine);

qui sera de tout de manière plus long car sans délimiteurs: le parseur y est obligé de faire plus d'un aller retour sur la chaîne.


POO PHP+Ajax en MVC avec PDO et Bases de données épaisses  : What else?

Hors ligne

#24 24-02-2011 20:42:52

mcAllan
Mowdérateur
Lieu : Châteaurenard en Provence
Inscription : 08-05-2009
Messages : 269

Re : Y a un roi des RegExp ici ?

Pour info et pour ceux qui n'ont pas connu, le site créé par Yves existe toujours même s'il n'est pas actif.
C'est une référence...
http://www.expreg.com/


Promotion de PPOO : Programmation Propre Orientée Objet !!
Recommande AAO : Apéritif Avec Olives...
Glop, glop

Hors ligne

#25 24-02-2011 23:03:05

Maljuna Kris
Infantimigulo
Lieu : Douarnenez 29100 Breizh Izel
Inscription : 08-05-2009
Messages : 2 453
Site Web

Re : Y a un roi des RegExp ici ?

mcAllan a écrit :

[code php]
$result = preg_replace('`(\/\*.*\*\/)`Uis', '', $source);
[/code]

Ah les feignasses ! C'est moi le nul en regexp qui doit commenter et/ou expliquer
Donc ce vieux renard de mcAllan nous a choisi `comme délimiteur plutôt que #, ce qui est loin d'être idiot car `est surement moins fréquent que #
Donc lui, son astuce tient au couplage des trois options Uis, après le motif.
Que nous dit le site expreg.com à ce sujet

U
(PCRE_UNGREEDY)     Cette option inverse la tendance à la gourmandise des expressions régulières. Vous pouvez aussi inverser cette tendance au coup par coup avec un ?. De même, si cette option est activée, le ? rendra gourmand une séquence. Cette option n'est pas compatible avec Perl. Elle peut aussi être mise dans le masque avec l'option

i
(PCRE_CASELESS)     Effectue une recherche insensible à la casse. Dans les POSIX, chaque fonction a son équivalent insensible à la casse :
ereg / eregi - split / spliti - etc...
Avec les PCRE, il suffit simplement d'ajouter le i comme option pour rendre le motif insensible à la casse. PCRE offre également l'opportunité de gérer les options au coup par coup, sur une partie seulement des motifs de recherche. Nous verrons cela en détail dans une autre partie du cours.

s
(PCRE_DOTALL)     Avec cette option, le méta caractère point (.) remplace n'importe quel caractère, y compris les nouvelles lignes. Sans cette option, le caractère point ne remplace pas les nouvelles lignes. Cette option est équivalente à l'option Perl /s. Une classe de caractères négative telle que [^a] acceptera toujours les caractères de nouvelles lignes, indépendamment de cette option.

Bon, bah je ne suis pas plus avancé, je ne capte rien.


Gloire à qui n'ayant pas d'idéal sacro-saint,
Se borne à ne pas trop emmerder ses voisins. G. Brassens Don Juan 1976.
Avĉjo MoKo kantas
La chaîne YouTube MoKo Papy

Hors ligne

Pied de page des forums