8797 sujets

Développement web côté serveur, CMS

Bonjour à tous.

Je vous explique sommairement mon problème.

J'ai une variable de type string qui contient l'entièreté d'un post type de blog, qui pourrait contenir des balises <pre class="un_truc"></pre>.

Ce que je souhaiterai faire, c'est analyser cette chaine pour :
- avoir un tableau avec la valeur de chaque élément class des balises <pre>
- avoir un autre tableau avec la valeur de contenu de chacune de ces balises <pre>

et enfin le moyen de pouvoir, toujours dans la chaine originale, remplacer le contenu de toutes les balises pre par le contenu d'un tableau (qui résultera du traitement des deux tableaux précédents).

J'espère avoir été relativement clair, j'essaie depuis toute à l'heure de bidouiller avec les fonctions preg_match, preg_replace, etc... Et je n'arrive à rien du tout, si ce n'est pas perspective presque certaine d'une migraine carabinée en bout de course...

Quelqu'un pour me donner un coup de main ?

Merci bcp.
Modifié par Lisarael (13 Jul 2005 - 13:09)
J'aurai du mal à te donner une réponse correcte, je ne suis pas un champion des regex, néanmoins, je te recommande un excellent tuto ICI
merci Cyrano, mais je viens de passer trois heures plongé dans des tutos du style pour ne rien comprendre, d'où le post... je suis lamentablement perdu...
un exemple concret ?

ben, je prends un post d'exemple:


<p>Voici une petite fonction générique pour transformer un xml via une xsl, le tout en php.</p>

<pre class="php">&lt;?php
	// fonction xslTransform(), processeur de tranformation xml/xsl
	function xslTransform($xmlPath, $xslPath) {

		// routine de création du chemin de fichier
			$path1 = $_SERVER['SCRIPT_FILENAME'];
			$regExp = "[A-Za-z0-9]*\.php";
			$path2 = spliti($regExp, $path1);
			
			$verif = substr($path2[0], 0, 3);
			
			if ($verif == "e:/"){
				$path = "file:///".$path2[0];
				$pathNoFile = $path2[0];
				}
			else {
				$path = "";
				$pathNoFile = "";
				}
		// fin routine de création du chemin de fichier
		
		$xslFile = $path .$xslPath;
		
		$xmlFile = domxml_open_file($path .$xmlPath);
		
		$xsldoc = domxml_xslt_stylesheet_file($xslFile);
		$result =  $xsldoc->process($xmlFile);

		print $xsldoc->result_dump_mem($result);

	}
?&gt;</pre>

<p>Ensuite, pour appeller la fonction, vous devrez faire :</p>
<pre class="php">&lt;?php xslTransform("xml/messages.xml", "xml/styles.xsl") ?&gt;</pre>

<p>Et c'est tout !</p>


l'intégralité du post est stocké dans une variable php, disons $contenuPost.

Ce que je veux, c'est tripatouiller cette variable pour en tirer les valeurs de classes des éléments <pre>, et les contenus de ceux-ci.

via ces paramètres, stockés dans des variables, faire quelques opérations (pas encore d'idées précises quant à celles-ci, mais de toutes façon ça importe peu), puis, utiliser les nouveaux contenus pour remplacer, dans la chaine originale du post, les contenus des <pre> par les nouveaux contenus (principalement pour de la coloration syntaxique, entre autres choses)

j'espère que c'est un peu plus clair.

merci.
Mon problème n'est pas encore tout à fait résolu mais presque, je suis arrivé à des résultats plus que concluants, je triture le tout dans tous les sens demain et je viens poster la solution.

encore un ENÔÔÔRME merci à Marvin le rouge qui a "perdu" une partie de sa soirée à me mener sur la bonne piste... Smiley lol

bonne nuit à tous.
bon, voilà, c'est fini, je suis arrivé au bout.

voici le code final du truc, c'est encore un peu brouillon, mais le principal y est.

<?php
/**
Classe geshiPlug

coloration du code des balises pre avec une class correspondant à leur langage
*/

class geshiPlug {
	
	function dcPostContent($part=0) {
		
		global $news;
		
		/*
		correspondances du tableau de sortie
			$out[0][x] => balises <pre> + class + contenu (comme figure dans la chaine $contenuPost)
			$out[1][x] => classe de la balise pre
			$out[2][x] => contenu de la balise pre
		*/	
		
		# stockage du contenu du post dans une variable
		$contenuPost = $news->getContent();
		
		$regPattern = "|<pre class=\"([^>]+)\">(.*)</pre>|sU";
		$oldRegPattern2 = "|<pre class=\"[^>]+\">(.*)|sU";	// utilisée sur un preg_replace qui ne marchait pas, je garde quand même au cas où...
		$regPattern2 = "<pre class=\"[^>]+\">(.*)";		
		$preModified = array();
		$postModified = array();
		
		if( preg_match_all($regPattern, $contenuPost, $out, PREG_PATTERN_ORDER) ) {
			
			// le preg match a trouvé des instances de <pre>, stockées dans le Array $out selon la correspondance écrite plus haut.
			for($i=0; $i < (count($out[0])); $i++) {
				$classe = $out[1][$i];
				$contenu = $out[2][$i];
				$preModified[$i] = dcGeshiLight($contenu, $classe);
			}
			
			$contenuPostExploded = explode("</pre>", $contenuPost);
			
			for($i=0; $i < (count($contenuPostExploded)-1); $i++) {
				$postModified[$i] = ereg_replace($regPattern2, $preModified[$i], $contenuPostExploded[$i]);
			}
			$postModified[$i+1] = $contenuPostExploded[$i];
			
			for($i=0; $i < (count($postModified)-1); $i++) {
				echo $postModified[$i];
			}
			echo $postModified[$i+1];
		}
		else {
			// le preg_match ne fonctionne pas (pas d'instance de pre), donc on affiche le post normalement
			echo $news->getContent();
		}		
	}
	
	
	
	function dcPostAbstract($s='%s',$l='<p><a href="%s" title="Read %s">Read next</a></p>') {
		global $news;
			
		if ($news->f('post_chapo') != '') {
			printf($s,$news->getChapo());
			printf($l,$news->getPermURL(),$news->f('post_titre'));
		} else {
			
			$contenuPost = $news->getContent();
			
			$regPattern = "|<pre class=\"([^>]+)\">(.*)</pre>|sU";
			$oldRegPattern2 = "|<pre class=\"[^>]+\">(.*)|sU";	// utilisée sur un preg_replace qui ne marchait pas, je garde quand même au cas où...
			$regPattern2 = "<pre class=\"[^>]+\">(.*)";		
			$preModified = array();
			$postModified = array();
			
			if( preg_match_all($regPattern, $contenuPost, $out, PREG_PATTERN_ORDER) ) {
				
				// le preg match a trouvé des instances de <pre>, stockées dans le Array $out selon la correspondance écrite plus haut.
				for($i=0; $i < (count($out[0])); $i++) {
					$classe = $out[1][$i];
					$contenu = $out[2][$i];
					$preModified[$i] = dcGeshiLight($contenu, $classe);
				}
				
				$contenuPostExploded = explode("</pre>", $contenuPost);
				
				for($i=0; $i < (count($contenuPostExploded)-1); $i++) {
					$postModified[$i] = ereg_replace($regPattern2, $preModified[$i], $contenuPostExploded[$i]);
				}
				$postModified[$i+1] = $contenuPostExploded[$i];
				
				for($i=0; $i < (count($postModified)-1); $i++) {
					echo $postModified[$i];
				}
				echo $postModified[$i+1];
			}
			else {
				// le preg_match ne fonctionne pas (pas d'instance de pre), donc on affiche le post normalement
				echo $news->getContent();
			}		
			
		}
	}
	
}
?>


oui, oui, c'est pour un dotclear, et quand j'en aurai le courage, je le nettoirai un peu et j'en ferai un plugin que je proposerai chez eux.

encore merci à Marvin le rouge, sans son aide, je n'aurai pas fini à l'heure actuelle.