Compter les mots dans un chaîne PHP

© Christian PAULUS. Document créé le 31 août 2010 , mis à jour le 31 août 2010.

La mémoire est souvent la qualité de la sottise. Chateaubriand

Accueil du site > Astuces > PHP > Compter les mots dans un chaîne PHP

str_word_count / PHP 5.3.3

La fonction PHP str_word_count() permet de compter les mots dans une chaîne de caractères.

Pour le test ci-dessous, qui démontre que le résultat est faux pour un texte en français, le pangramme suivant est utilisé :

2010 : Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l’alcôve ovoïde, où les bûches se consument dans l’âtre, ce qui lui permet de penser à la cænogénèse de l’être dont il est question dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, pense-t-il, diminue çà et là la qualité de son œuvre.

Le 2010 a été ajouté au célèbre pangramme, car dans ce cas, ne doit-il pas être considéré comme un mot ?

Le script de test str_word_count()

<?php

// http://www.quesaco.org/Compter-les-mots-dans-un-chaine-PHP

// la chaîne pour le test. Pangramme complet.
$s = "2010: Portez ce vieux whisky au juge blond "
        . "qui fume sur son île intérieure, à côté de l'alcôve ovoïde, "
        . "où les bûches se consument dans l'âtre, ce qui lui permet de penser "
        . "à la cænogénèse de l'être dont il est question dans la cause ambiguë "
        . "entendue à Moÿ, dans un capharnaüm qui, pense-t-il, diminue çà et là "
        . "la qualité de son œuvre.";

// caractères accentués FR et autres composants de mot
$chars = "àâæçéèêëïîôœùüûÿ0123456789-'";

define('BR', '<br />'."\n");
// pour le test
define('LOOPS', 1000);

// http://fr.php.net/manual/fr/function.str-word-count.php#85579
define("WORD_COUNT_MASK", "/\p{L}[\p{L}\p{Mn}\p{Pd}'\x{2019}]*/u");
function str_word_count_utf8($str)
{
        return preg_match_all(WORD_COUNT_MASK, $str, $matches);
}

echo(
"<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='fr' lang='fr' dir='ltr'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
</head>
<body>
<pre>");

foreach(($r = str_word_count($s,2,$chars)) as $key=>$val)
{
        echo(str_pad($key, 4, ' ', STR_PAD_LEFT).': '.$val.'<br />'."\n");
}

echo('</pre>'
        . BR
        . 'Nombre de mots avec str_word_count() sans charlist : '
                . str_word_count($s,0) . BR
        . 'Nombre de mots avec str_word_count() avec charlist : '
                . count($r) . BR
        . 'Nombre de mots avec str_word_count_utf8() : '
                . str_word_count_utf8($s) . BR
        );

// mesure de performance: str_word_count() sans tableau
for($time = microtime(), $ii = 0; $ii < LOOPS; $ii++) {
        $r = str_word_count($s,0,$chars);
}

$time = microtime() - $time;
echo('str_word_count sans tableau: ' . $time . ' micro-sec.' . BR);

// mesure de performance: str_word_count() avec tableau
for($time = microtime(), $ii = 0; $ii < LOOPS; $ii++) {
        $r = str_word_count($s,2,$chars);
}

$time = microtime() - $time;
echo('str_word_count avec tableau: ' . $time . ' micro-sec.' . BR);

// mesure de performance: preg_match_all()
for($time = microtime(), $ii = 0; $ii < LOOPS; $ii++) {
        $r = preg_match_all(WORD_COUNT_MASK, $s, $matches);
}

$time = microtime() - $time;
echo('str_word_count_utf8: ' . $time . ' micro-sec.' . BR);

echo(BR
         . '</body></html>');

?>

Ce code lance d’abord trois premiers tests :

  • appel à la fonction str_word_count() sans préciser les caractères complémentaires devant être considérés comme éléments de mot. Le résultat est : 68 mots. str_word_count() considère les caractères accentués comme des espaces et fausse le résultat en comptant bien plus de mots qu’il y en a dans la chaîne.
  • appel à cette même fonction en précisant les caractères devant être considérés comme éléments de mot. Le résultat est 62 mots.
  • appel à la fonction proposée par om+www accompagnée d’une excellente explication en français sur php.net, pour un total de 61 mots.

Dans les deux derniers cas, nous sommes proches de la réalité. Le tout est de décider si le "2010" présent en début de phrase doit être considéré comme un mot.

Performance str_word_count() vs preg_match_all()

En fin de script, le test mesure le temps nécessaire à la réalisation de l’opération. Le résultat est, pour une boucle lançant 1000 fois l’opération :

  • str_word_count sans tableau : 0.004571 micro-sec.
  • str_word_count avec tableau : 0.01758 micro-sec.
  • str_word_count_utf8 : 0.053966 micro-sec.

Télécharger le script de test

Voici le script de ce test compressé au format ZIP. Attention : ce script est au format UTF-8. Si les caractères accentués n’apparaissent pas correctement, prendre un éditeur de texte compatible :

Zip - 1.2 ko
Le script de test str_word_count.php

Plussoyez !

Les forums sont fermés.