Expression régulière casse-tête

Expression régulière casse-tête - PHP - Programmation

Marsh Posté le 13-01-2006 à 11:20:30    

Bonjour,
 
J'ai une page HTML qui contient des liens relatifs, que je souhaiterais remplacer par des liens absolus.
 
D'où utilisation d'une expression régulière, mais là je commence à avoir un sérieux mal de crâne, surtout pour un vendredi matin.
 
Je cherche toutes les chaînes contenant src= avec ou sans espace avant ou après le signe = avec ou sans guillemets et qui n'est pas suivi de http.
 
Ce qui me donne

Code :
  1. eregi_replace('src= ?"? *^(http)', "src=" . $path, $variable)


 
Sauf que ça ne marche pas. Est-ce que quelqu'un peut me dire ce qui cloche dans cette expression?

Reply

Marsh Posté le 13-01-2006 à 11:20:30   

Reply

Marsh Posté le 13-01-2006 à 11:36:55    

try this:

Code :
  1. /src(\s|)=(\s|)('|" )(?!(http))(.*?)('|" )/


 
par contre tu auras besoin de preg plutot que de ereg pour que ça marche

Reply

Marsh Posté le 13-01-2006 à 11:37:14    

Code :
  1. preg_replace('!href src="^(?:http://)([^"].*)"!si', 'href src="' . $path . '$1"', $variable);


 
Pas certain que ca marche. je prends toute chaine commencant par href src=", n'ayant pas d'URL debutant par http:// (chaine non capturante ?:), et je capture tout le reste jusqu'au premier ". Par contre, les liens en https, ftp, etc... vont merder.
 
Je pars du principe que l'on a:
 
<href src="/toto/titi.html/">

Message cité 1 fois
Message édité par cinocks le 13-01-2006 à 11:40:44

---------------
MZP est de retour
Reply

Marsh Posté le 13-01-2006 à 11:46:18    

anapajari a écrit :

try this:

Code :
  1. /src(\s|)=(\s|)('|" )(?!(http))(.*?)('|" )/


 
par contre tu auras besoin de preg plutot que de ereg pour que ça marche


 
J'ai rien compris à cette expression, mais

Code :
  1. preg_replace("src(\s|)=(\s|)('|\" )(?!(http))(.*?)('|\" )", "src=$path", $variable)


donne

Citation :

Warning: Delimiter must not be alphanumeric or backslash in c:\weblocal\sites\charlemagne\php\mailer.php on line 33


Message édité par daviso le 13-01-2006 à 11:51:05
Reply

Marsh Posté le 13-01-2006 à 11:54:46    

cinocks a écrit :

Code :
  1. preg_replace('!href src="^(?:http://)([^"].*)"!si', 'href src="' . $path . '$1"', $variable);


 
Pas certain que ca marche. je prends toute chaine commencant par href src=", n'ayant pas d'URL debutant par http:// (chaine non capturante ?:), et je capture tout le reste jusqu'au premier ". Par contre, les liens en https, ftp, etc... vont merder.
 
Je pars du principe que l'on a:
 
<href src="/toto/titi.html/">


 
En fait, les adresses en href ont déjà sauté, il ne reste que celles du type <img src="../toto/titi/blabla.jpg">
Sauf que rien ne garantit que le premier argument du img sera src plutôt que border ou un autre, qu'il n'y aura pas un espace après le src ou après le =, qu'il y aura ou non des guillemets. Par contre, les liens en ftp et https me semblent peu probables.

Reply

Marsh Posté le 13-01-2006 à 11:57:30    

bin manque les slashs que j'ai mis au début et à la fin ... [:pinguino]
 
en gros la regex ça fait:

Code :
  1. /
  2. src                          # commence par src
  3. (\s|)                        # suivi d'un espace ou de rien
  4. =                            # suivi d'un égal
  5. (\s|)                       # suivi d'un espace ou de rien
  6. ('|" )                        # suivi d'une quote ou d'une guillement
  7. (?!(http))                 # assertion négative: suivi de "pas http"
  8. (.*?)                       # tout et n'importe quoi
  9. ('|" )                        # terminé par quote ou guillement
  10. /


 
ps: je sais jamais si on dit assertion négative ou insertion négative, mais c'est un truc dans le genre...

Message cité 1 fois
Message édité par anapajari le 13-01-2006 à 11:59:44
Reply

Marsh Posté le 13-01-2006 à 12:07:11    

anapajari a écrit :

bin manque les slashs que j'ai mis au début et à la fin ... [:pinguino]
 
en gros la regex ça fait:

Code :
  1. /
  2. src                          # commence par src
  3. (\s|)                        # suivi d'un espace ou de rien
  4. =                            # suivi d'un égal
  5. (\s|)                       # suivi d'un espace ou de rien
  6. ('|" )                        # suivi d'une quote ou d'une guillement
  7. (?!(http))                 # assertion négative: suivi de "pas http"
  8. (.*?)                       # tout et n'importe quoi
  9. ('|" )                        # terminé par quote ou guillement
  10. /


 
ps: je sais jamais si on dit assertion négative ou insertion négative, mais c'est un truc dans le genre...


 
Ca, ça marche presque (saloperie de slashs), sauf qu'il remplace toute l'adresse, par le $path, sans laisser le nom du fichier derrière, et qu'il ne referme pas le guillemet s'il y en avait un (src="../toto/titi.jpg" est remplacé par src="http://monserveur.fr/charlemagne/buzzy/php/ )
 
On peut aussi faire ça en expression régulière?

Reply

Marsh Posté le 13-01-2006 à 12:43:43    

le nom de ton fichier tu dois l'avoir dans $4.
 
Essaye un truc dans le genre:

Code :
  1. preg_replace("src(\s|)=(\s|)('|\" )(?!(http))(.*?)('|\" )", "src=\"$path$4\"", $variable)

Reply

Marsh Posté le 13-01-2006 à 12:53:45    

anapajari a écrit :

le nom de ton fichier tu dois l'avoir dans $4.
 
Essaye un truc dans le genre:

Code :
  1. preg_replace("/src(\s|)=(\s|)('|\" )(?!(http))(.*?)('|\" )/", "src=\"$path$4\"", $variable)



 
Après vérification, $4 est vide ($3 aussi d'ailleurs). J'ai rajouté les slashs au début et à la fin de l'expression régulière, sinon j'avais encore un message d'erreur.

Reply

Marsh Posté le 13-01-2006 à 13:52:56    

oui pas de bol c'était dans $5 je sais pas compter :o
et effectivement j'avais oublié les '/' autour ;)

Reply

Marsh Posté le 13-01-2006 à 13:52:56   

Reply

Marsh Posté le 13-01-2006 à 14:12:50    

[:youpi]
 
Ca marche ! Je vais ouvrir une souscription pour t'élever une statue.
 
 :jap:

Reply

Marsh Posté le 13-01-2006 à 14:24:42    

Pourquoi (\s|) et pas simplement \s? ?
 
Ca éviterait de catcher 40 trucs et de devoir compter les parenthèses pour trouver la bonne.


Message édité par sielfried le 13-01-2006 à 14:25:11

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 13-01-2006 à 14:31:44    

TIMTOWTDI :D
Perso j'ai l'habitude de tout catcher dans ces cas la pour remettre exactement comme s'était avant.

Reply

Marsh Posté le 13-01-2006 à 17:12:23    

Je voulais apporter mon grain de sel a la discussion et puis je suis tombé sur un cas etrange ... si klk1 peut m'expliquer le disfonctionnement que voici :
 
pattern : #<(.*)src\s?=\s?("|')?(?!http://)([^ ]*)\1(.*)>#Uis
replace : <\1src="http://pouetpouet\3"\4>
 
donc remplacer le pattern par le masque de remplacement ci dessus. Or le pattern ne matche rien. C'est etrange parce que le pattern suivant match exactement ce qu'il faut et fonctionne LUI.
 
#<.*src\s?=\s?("|')?(?!http://)([^ ]*)\1(.*)>#Uis
 
C'est exactement le meme masque de recherche a ceci pres que j'ai oté les parentheses capturantes autour du premier .*
 
En résumé :
#<.*src\s?=\s?("|')?(?!http://)([^ ]*)\1(.*)>#Uis fonctionne !
#<(.*)src\s?=\s?("|')?(?!http://)([^ ]*)\1(.*)>#Uis ne fonctionne pas :s
 
evidemment la version avec les parentheses capturantes est plus interressantes car dans le replace elles vont permettre de reconstruire la balise d'origine.
 
Quelqu'un saurait expliquer ce comportement ... tres certainement normal mais que je ne saisis pas.

Reply

Marsh Posté le 13-01-2006 à 17:30:35    

T'as un exemple ?
 
J'ai testé ça et ça passe très bien :
 

Code :
  1. $pattern = '#<.*src\s?=\s?("|\')?(?!http://)([^ ]*)\1(.*)>#Uis';
  2. $replace = 'bar';
  3. echo preg_replace($pattern, $replace, '<img src="foo.gif" />');


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 13-01-2006 à 17:33:33    

c'est le pattern avec (.*) des le debut qui ne fonctionne pas.
l'interet des parentheses etant de pouvoir reconstruire le debut de la balise et la fin de la balise dans le replace qui permet juste de modifier le contenu du src.

Reply

Marsh Posté le 13-01-2006 à 17:37:36    

Arf, j'ai inversé les deux.
 
Effectivement ça a pas l'air de passer avec les parenthèses. Mais plus le temps de regarder ça maintenant.  
 
Je me remettrai dessus dans la soirée, ça m'intéresse.


Message édité par sielfried le 13-01-2006 à 17:37:53

---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 13-01-2006 à 17:40:54    

Bon ben c'est ta référence \1 qui fait déconner, elle essaie de catcher le (.*) si tu mets des parenthèses là.


---------------
StarCraft Professional Gaming Database | [Ze Topic] Starcraft/BroodWar
Reply

Marsh Posté le 13-01-2006 à 17:42:39    

Merci beaucoup ;) le petit detail qui passait inapercu  :sweat:  
 
Edit : lol la suppression ;)
 
Solution :
pattern : #<(.*)src\s?=\s?("|')?(?!http://)([^ ]*)\2(.*)>#Uis
replace : <\1src="http://pouetpouet\3"\4>


Message édité par afbilou le 13-01-2006 à 17:43:06
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed