Forum Clubic

[PHP] Expressions régulières - pour nettoyer des balises (X)HTML

Bonjour à tous, voilà quelques jours que je planche sur une expression régulière qui me permettrait de "nettoyer" des balises (X)HTML. Mon problème est le suivant :

Dans un code type :

<balise x="machin" param="truc" y="bidul" z=1>

J’aimerai pouvoir le transformer en :

<balise param="truc">

sachant que je ne sais ni le nom, ni la valeure de x, y et z, que ceux-cis sont optionnels et que les "" ne sont pas forcement présents.

Si un Dieu en expression réulières passe, merci de m’aider

Il y a toujours un seul paramètre à garder, ou il peut y en avoir plusieurs ?

un seul pour le moment mais je pens e que je pourais changer le code si j’en ai plusieurs à récupérer.

Merci de m’aider :slight_smile:

C’est PHP4, ou PHP5 ? Peut-être qu’il serait plus simple et sûr d’utiliser DOM (avec loadHTML ou loadHTMLFile puisque les documents que tu traites ne semblent pas valides XML). Ensuite tu parcours l’arbre XML à l’aide d’une fonction récursive, ou alors tu récupères les éléments que tu veux modifier à l’aide de XPath, et tu modifies ce qu’il faut.

J’ai essayé avec les expressions régulières, je reconnais ne pas avoir réussi à faire ce que tu voulais. Voici ce que j’ai obtenu, cependant.

<?php

function replace($matches) {
	print_r($matches);
	
	$accept = array('param', 'y');
	$result = '<'.$matches[1].' ';
	$count = count($matches);
	
	for ($i = 2; $i < $count; $i += 2)
  if (in_array($matches[$i], $accept))
  	$result .= $matches[$i].'='.$matches[$i + 1].' ';
	
	return $result.'>';
}

$subject = '<balise x=machin y="bidul" z="1" param="truc" >';
//$pattern = '/<([[:alnum:]]+)([ ]+([[:alnum:]]+)=("[^"]*"|[^ ]+)[ ]*)*>/i';
$pattern = '/<([[:alnum:]]+)(?:[ ]+([[:alnum:]]+)=("[^"]*"|[^ ]+)[ ]*)*>/i';

echo preg_replace_callback($pattern, 'replace', $subject);

?>

Le problème de ce code, c’est que la fonction callback replace ne reçoit que le dernier attribut de la balise, comme tu peux le voir si tu exécutes le script. Peut-être y’a-t-il un moyen de construire un pattern qui n’écraserait pas chaque nouvelle capture par une précédente, mais je l’ignore. Je ne me débrouille pas formidablement bien avec les expressions régulières.

On peut aussi filtrer simplement les attributs, avec un pattern de ce genre : i=("[^"]*"|[^ ]+)[/i]. Mais c’est risqué étant donné qu’il peut très bien y avoir ce genre de chaînes en dehors de la déclaration d’une balise, et qu’on perd l’avantage de connaitre la balise qui contient l’attribut.

Bref, je pense que le moyen le plus sûr pour ne pas avoir d’erreur est la solution DOM + éventuellement XPath… Mais peut-être que quelqu’un a mieux :slight_smile:

+1 loadHTML

Le mieux reste quand même (dans ce cas) de faire une regexp à la main :

strpos(’<balise’ );

et on analyse l’entrée : strpos(‘param’), etc.

C’est pas plus goret qu’une regexp et ça permet de traîter bien plus de cas.

(vi, les regexp ne peuvent pas tout)

Merci à vous deux, je vais voir ce que je peux faire avec ce que vous avez donné :slight_smile: