8797 sujets

Développement web côté serveur, CMS

Bonjour à tous, j'avais déjà parlé ici de problème de translitération (caractères spéciaux pour les hiéroglyphes). J'aimerais chercher dans une requete tous les éléments qui comment par
<span class="transliteration">wDA</span>
, et par exemple si je trouve dans cet emplacement un "D", je le remplace par "&#7695;" (d souligné en UTF8). Bien entendu, je veux conserver l'intégralité du texte, ainsi que le <span class="transliteration"></span> et modifier uniquement ce qui se trouve entre les deux tags de ce span (et non pas tous les "D" du texte...)... J'ai tenté un preg_replace en recherchant les spans, mais je n'arrive pas à changer que ce qu'il y a dedans. Après j'ai tenté un preg_replace_callback avec une fonction remplacement basé sur des
$chaine = str_replace ( 'D', '&#7695;', $chaine );
mais ça ne fonctionne pas. Quelqu'un aurait une idée de comment faire ? Voici mon test preg_replace :
 $definition = preg_replace('`<span class="transliteration">([D>]+)</span>`', '<a href="$1" target="_blank">$1</a>', $definition);

Modifié par montoumes (20 Aug 2008 - 17:06)
Salut,

on doit sûrement pouvoir optimiser ce qui suit (et d'ailleurs un preg_replace suffirait certainement) mais tu pourrais essayer :
<?php
$contenu = file_get_contents('test.html');

// Fonction de callback
function souligne_D($matches)
{
	$chaine = str_replace ( 'D', '&#7695;', $matches[1] );
	return '<span class="transliteration">'.$chaine.'</span>';
}
$regex = '#<span class="transliteration">(.*?)</span>#';
echo preg_replace_callback(
            $regex,
            "souligne_D",
            $contenu);
?>

A+
Ah si j'ai quand même encore une petite question : la fonction fonctionne pour un caractère donc mon D est bien remplacé par le code; par contre comment la faire fonctionner avec plusieurs ?
function transliteration($matches)
	{
		$chaine = str_replace ( 'D', '&#7695;', $matches[0] );
		$chaine = str_replace ( 'A', '<em>3</em>', $matches[0] );
		$chaine = str_replace ( 'S', '&#352;', $matches[0] );
		$chaine = str_replace ( 'T', '<u>T</u>', $matches[0] );
		$chaine = str_replace ( 'X', '<u>h</u>', $matches[0] );
		return '<span class="transliteration">'.$chaine.'</span>';
	}
et
$regex = '#<span class="transliteration">(.*?)</span>#';					
$definition = preg_replace_callback($regex,"transliteration", $definition);
Ici seul le cas du X est appliqué... C'est le matches[0] qui pose problème ?
Modifié par montoumes (20 Aug 2008 - 17:21)
montoumes a écrit :
C'est le matches[0] qui pose problème ?
Oui... et aussi le fait qu'il faut faire le str_replace sur $chaine à partir de la seconde fois :
<?php
$contenu = file_get_contents('test.html');

// Fonction de callback
function souligne_D($matches)
{
	$chaine = str_replace ( 'D', '&#7695;', $matches[1] );
	$chaine = str_replace ( 'A', '<em>3</em>', $chaine );
	$chaine = str_replace ( 'S', '&#352;', $chaine );
	$chaine = str_replace ( 'T', '<u>T</u>', $chaine );
	$chaine = str_replace ( 'X', '<u>h</u>', $chaine );
	return '<span class="transliteration">'.$chaine.'</span>';
}
$regex = '#<span class="transliteration">(.*?)</span>#';
echo preg_replace_callback(
            $regex,
            "souligne_D",
            $contenu);
?>
Merci ça fonctionne ! Par contre je ne comprends pas : pourquoi les str_replace qui suivent n'ont plus besoin de la référence $matches[1] ?
Parce que $matches[1] contient la chaîne de caractères trouvée entre <span...> et </span> et que cette valeur ne change pas tout au long de la fonction. Après le premier str_replace la variable $chaine contient la valeur de $matches[1] après qu'un éventuel D ait été trouvé et remplacé et c'est donc cette chaîne qu'il faut continuer d'analyser.

Pour être plus clair :
<?php
$str = 'ABCDE'; // cette valeur ne sera jamais modifiée
$chaine = str_replace ( 'A', 'a', $str); // -> $chaine vaut 'aBCDE';
$chaine = str_replace ( 'B', 'b', $chaine); // -> $chaine vaut 'abCDE';
$chaine = str_replace ( 'C', 'c', $chaine); // -> $chaine vaut 'abcDE';
?>
MAIS

<?php
$str = 'ABCDE'; // cette valeur ne sera jamais modifiée
$chaine = str_replace ( 'A', 'a', $str); // -> $chaine vaut 'aBCDE';
$chaine = str_replace ( 'B', 'b', $str); // -> $chaine vaut 'AbCDE';
$chaine = str_replace ( 'C', 'c', $str); // -> $chaine vaut 'ABcDE';
?>
En repassant par là je me rends compte qu'il aurait été plus simple et plus lisible de faire :
<?php
$contenu = file_get_contents('test.html');
// Fonction de callback
function souligne_D($matches)
{
	$replace = array(
		"D" => "&#7695;", 
		"C" => "<em>3</em>", 
		"S" => "Š", 
		"T" => "<u>T</u>", 
		"X" => "<u>h</u>"
	);
	$chaine = strtr($matches[1], $replace);
	return '<span class="transliteration">'.$chaine.'</span>';
}
$regex = '#<span class="transliteration">(.*?)</span>#';
echo preg_replace_callback(
            $regex,
            "souligne_D",
            $contenu);
?>