Post by mostafala fonction str_word_count ne marche pas sur une chaine codée en
utf-8; y-a-il une autre façon de compter le nombre de mots d'une
chaine codée en utf-8 ?
Je vais essayer de proposer une solution. [...]
La voilà. Elle est très courte, sauf que j'ai cru utile de la documenter
abondamment, ce qui augmente pas mal la taille du truc...
<?php
/*
* Explications du masque pour preg_match_all.
*
* La fonction str_word_count standard considère qu'un mot est
* une séquence de caractères qui contient tous les caractères
* alphabétiques, et qui peut contenir, mais pas commencer
* par "'" et "-".
*
* Avec Unicode et UTF-8, une lettre peut être un caractères
* ASCII non accentué tel que "e" ou "E", mais aussi un "é" ou
* un "É", lequel peut se représenter sous la forme de deux
* caractères : d'abord le "E" non accentué, puis l'accent tout
* seul. Une lettre "E" ou "É" fait partie de la classe « L »,
* un accent de la classe « Mn ».
*
* Par ailleurs, "-" n'est plus le seul trait d'union possible.
* Plutôt que de les lister individuellement, j'ai choisi de
* tester les caractères de la classe « Pd ». Un inconvénient
* est que cela inclut aussi le tiret cadratin et d'autres,
* mais cet inconvénient existait déjà avec str_word_count et
* le tiret ascii, et en outre il ne concerne pas le français
* (contrairement à l'anglais, il y a toujours des espaces
* autour de ces tirets).
*
* Enfin, "'" n'est pas non plus la seule apostrophe possible.
* Mais contrairement aux tirets je teste juste l'apostrophe
* typographique U+2019 à part au lieu de tester la classe « Pf »
* car cette dernière contient trop de signes de ponctuation
* à exclure de la définition d'un mot.
*
* Un mot commence donc par une lettre \p{L}, éventuellement
* accentuée (suivie par un nombre quelconque de \p{Mn}), et
* ensuite on peut rencontrer un nombre quelconques d'autres
* lettres (\p{L} et \p{Mn}), de tirets (\p{Pd}) ou d'apostrophes
* (' et \x{2019}). Tout ceci, bien sûr, dans un masque compatible
* avec UTF-8 (/u à la fin).
*
* Pour les références, voir :
*
http://fr2.php.net/manual/fr/regexp.reference.php#regexp.reference.unicode
* http://fr2.php.net/manual/fr/reference.pcre.pattern.modifiers.php
*/
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);
}
?>
Cordialement,
--
Olivier Miakinen