Envoyé par unreal
Il arrive souvent qu'on ait besoin de limiter la longueur d'un texte, par exemple quand on souhaite afficher une news sur sa page d'accueil avec un lien "afficher la suite" quand la longueur dépasse un seuil.
En première approche, cela paraît facile à réaliser, mais les choses se compliquent quand le texte en question est du HTML. Hors de question alors de couper en plein milieu d'une balise contenant un espace (<a href...> par exemple) ou de couper sans refermer la balise.
Le petit script qui suit permet de retourner un nombre de mots donné, tout en refermant les balises proprement.
Petite remarque : il est tout à fait possible que le script ne renvoit pas exactement le nombre de mots spécifié. Ceci dit, le delta ne depasse pas 1 ou 2 mots, c'est pas vraiment la fin du monde.
Comme toujours, n'hésitez à faire part de vos remarques et critiques.
En première approche, cela paraît facile à réaliser, mais les choses se compliquent quand le texte en question est du HTML. Hors de question alors de couper en plein milieu d'une balise contenant un espace (<a href...> par exemple) ou de couper sans refermer la balise.
Le petit script qui suit permet de retourner un nombre de mots donné, tout en refermant les balises proprement.
<?php
function text_cut($str, $no_words_ret) {
// $str est la chaîne à couper
// $no_words_ret est le nombre de mots qu'on souhaite en retour
static $tags = array ('div', 'span', 'b', 'u', 'i', 'a', 'ul', 'li');
$word_count = 0;
$pos = 0;
$str_len = strlen($str);
$str .= ' <';
$open_tags = array ();
while ($word_count < $no_words_ret && $pos < $str_len) {
$pos = min(strpos($str, ' ', $pos), strpos($str, '<', $pos));
if ($str[$pos] == '<') {
if ($str[$pos + 1] == '/') {
array_pop($open_tags);
$word_count++;
} else {
$sub = substr($str, $pos + 1, min(strpos($str, ' ', $pos), strpos($str, '>', $pos)) - $pos - 1);
if (in_array($sub, $tags)) {
array_push($open_tags, $sub);
}
}
$pos = strpos($str, '>', $pos) + 1;
} else {
$pos++;
$word_count++;
}
}
$str = substr($str, 0, $pos);
if (count($open_tags) > 0) {
foreach($open_tags as $value) {
$str .= '</' . array_pop($open_tags) . '>';
}
}
return($str);
}
?>
function text_cut($str, $no_words_ret) {
// $str est la chaîne à couper
// $no_words_ret est le nombre de mots qu'on souhaite en retour
static $tags = array ('div', 'span', 'b', 'u', 'i', 'a', 'ul', 'li');
$word_count = 0;
$pos = 0;
$str_len = strlen($str);
$str .= ' <';
$open_tags = array ();
while ($word_count < $no_words_ret && $pos < $str_len) {
$pos = min(strpos($str, ' ', $pos), strpos($str, '<', $pos));
if ($str[$pos] == '<') {
if ($str[$pos + 1] == '/') {
array_pop($open_tags);
$word_count++;
} else {
$sub = substr($str, $pos + 1, min(strpos($str, ' ', $pos), strpos($str, '>', $pos)) - $pos - 1);
if (in_array($sub, $tags)) {
array_push($open_tags, $sub);
}
}
$pos = strpos($str, '>', $pos) + 1;
} else {
$pos++;
$word_count++;
}
}
$str = substr($str, 0, $pos);
if (count($open_tags) > 0) {
foreach($open_tags as $value) {
$str .= '</' . array_pop($open_tags) . '>';
}
}
return($str);
}
?>
Petite remarque : il est tout à fait possible que le script ne renvoit pas exactement le nombre de mots spécifié. Ceci dit, le delta ne depasse pas 1 ou 2 mots, c'est pas vraiment la fin du monde.
Comme toujours, n'hésitez à faire part de vos remarques et critiques.
Posté le 07/05/05 à 16:05