Comparaison insensible à la casse dans une liste (array)

FredoMkb
Invité n'ayant pas de compte PHPfrance

27 août 2006, 13:52

Bonjour à tous :)

Tout nouveau dans ce forum, et totalement débutant en Php, je bidouille en ce moment un petit code pour produire un petit sommaire à partir d'un texte fourni.

Ce sommaire respecte une syntaxe particulière, propre au CMS SPIP (pour ceux qui connaissent), mais la difficulté n'est pas vraiment là... je m'explique :

Je voudrais construire mon petit sommaire en récupérant les titres présents dans le texte d'un article. Ces titres sont tous entourés de 3 accolades, par exemple :

{{{Ceci est un titre}}}

Bien, grâce à un code que j'ai dégoté, j'arrive à récupérer tous les titres, voici l'instruction qui me permet de faire ça :
preg_match_all("|\{\{\{(.*)\}\}\}|U", $texteOrig, $regs);
Où "$texteOrig" est le texte entier de l'article et "$regs" est le résultat de la recherche, qui se matérialise par deux array, le second contenant les titres sans les accolades dont je me sert.

Maintenant, je souhaite comparer le contenu du second array pour savoir si un titre particulier existe, à savoir "Sommaire", c'est à dire que si ce titre n'existe pas dans la liste des titres récupérés, alors je ne construit pas le sommaire, dans le cas contraire je construit le sommaire de l'article.

Bon, la difficulté que je rencontre c'est que chaque rédacteur du site risque d'écrire le titre "Sommaire" un peu à sa sauce, parfois ce sera tout en minuscules, parfois tout en majuscules, etc... bref, pour l'instant j'utilise ce bout de code pour traiter les différents cas de figure les plus courrants :
preg_match_all("|\{\{\{(.*)\}\}\}|U", $texteOrig, $regs);
$sommList = array("sommaire", "Sommaire", "SOMMAIRE");
$sommText = "";
$titresList = $regs[1];
if (in_array ($sommList[0], $titresList)) {
$sommText = $sommList[0];
} elseif (in_array ($sommList[1], $titresList)) {
$sommText = $sommList[1];
} elseif (in_array ($sommList[2], $titresList)) {
$sommText = $sommList[2];
} else {
$sommText = "";
};
Mais je trouve ça un peu lourdingue :shock: ... sans parler que ça ne tient pas compte d'autres cas de figure qui pourraient se présenter (faute de frappe, etc.)...

Alors, ma question, comment savoir que le terme "Sommaire" existe bien dans la liste "$titresList" sans tenir compte de la casse ?

Merci à tous ceux qui voudront bien se pencher sur mon petit problème :)

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

27 août 2006, 14:31

C'est simple, il suffit de rendre ta recherche insensible à la casse avec l'option "i". De plus, je déconseille fortement d'utiliser des caractères spéciaux tels que "|" comme délimiteurs d'une expression rationnelle, à la place je recommande d'utiliser "#" mais d'autres personnes préfèreront "/" ou "!". Autre bonne pratique, concernant les backslashes "\" : pour utilier un backslash en tant que caractère dans une chaîne il faut le doubler afin de lui faire perdre ses propriétés spéciales (voir le manuel). Finalement, plutôt que d'utiliser l'option de recherche "U" (une option globale) je recommande plutôt d'utiliser un "?" dans ton masque.

Au final, ta fonction ressemble à:
preg_match_all('#\\{\\{\\{(.*?)\\}\\}\\}#i', $textOrig, $regs);

FredoMkb
Invité n'ayant pas de compte PHPfrance

27 août 2006, 15:24

Merci Hubert pour ta réponse :)
Au final, ta fonction ressemble à:
preg_match_all('#\\{\\{\\{(.*?)\\}\\}\\}#i', $textOrig, $regs);
Très intéressant tout ça, et tes remarques constructives...

Bon, je viens d'essayer ta propositon, mais, hélas, ça n'a pas l'air de fonctionner... :(

Voci mon petit bout de code, si ça peu aider à y voir plus clair :
<?php
function somm_table($texteOrig) {
	preg_match_all('#\\{\\{\\{(.*?)\\}\\}\\}#i', $texteOrig, $regs);
	$ok = 0;
	if (in_array ("sommaire", $regs[1])) {$ok = 1;};

	if ($ok == 1) {
		$nb = 1;
		foreach ($regs[1] as $item) {
			if ("sommaire" == $item) {
				$sommText = "{{{".$item."}}}";
				$texteNew = $texteNew."[somm<-]\r{{{".$item."}}}\r\r";
			} else {
				$texteNew = $texteNew."|[".$item."->#titre".$nb."]|<br />";
				$texteOrig = str_replace("{{{".$item."}}}", "<p>[titre".$nb."<-]".$item."</p>", $texteOrig);
				$nb++;
			};
		};
		$texteOrig = str_replace($sommText, $texteNew, $texteOrig);
	};
	return $texteOrig;
}
?>
Sinon, on vient de me signaler que la fonction "array_walk" pourrait me servir... mais bon, je ne sais pas bien comment :shock: (c'est chiant d'être aussi nul :( )

Merci pour ton aide :)

FredoMkb
Invité n'ayant pas de compte PHPfrance

27 août 2006, 17:29

Bon, voilà... avec un peu d'aide, j'ai enfin réussi à faire quelque chose avec la fonction "array_walk", voici ce que ça donne :
<?php
function convertirMinuscule(&$value, $key) {
	$value = strtolower($value);
};
$listeTitres = array("Introduction", "Sommaire", "Developpement", "Conclusion");
$result = array_walk($listeTitres, "convertirMinuscule");
$test = in_array("sommaire", $listeTitres);
print $test; // = 1
?>
Du coup, je vais pouvoir continuer le reste du code comme je l'avais prévu...

Encore merci Hubert pour ton aide :)