Discussion:
str_word_count et multibyte
(trop ancien pour répondre)
mostafa
2008-09-06 12:33:15 UTC
Permalink
Bonjour,

la 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 ?

Merci pour toute aide.
Olivier Miakinen
2008-09-06 16:56:59 UTC
Permalink
Bonjour,
Post by mostafa
la 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. Mais tout d'abord, je dois
savoir ce qu'est un mot selon str_word_count

<cit. http://fr3.php.net/str_word_count>
Dans cette fonction, la notion de "mot" dépend de la configuration de
localisation. C'est une chaîne qui contient tous les caractères
alphabétiques, et qui peut contenir, mais pas commencer par "'" et "-".
</cit.>

Une idée serait donc de compter par preg_match_all le nombre de fois où
l'on trouve une série commençant par un \pL et suivi d'un nombre
quelconque de \pL ou de « ' » ou de « - », le tout en mode UTF-8 :
http://fr2.php.net/manual/fr/regexp.reference.php#regexp.reference.unicode
http://fr2.php.net/manual/fr/reference.pcre.pattern.modifiers.php

Un truc du genre : "/\pL[-'\pL]/u"

Mais bon, il y a peut-être plus simple pour les lettres (ne pas prendre
en compte les lettres grecques par exemple) et inversement il faudrait
peut-être étendre la simple quote à l'apostrophe typographique, ou le
tiret ASCII à d'autres genres de traits d'union.

Est-ce que tu voudrais bien préciser quels sont les types de caractères
que tu peux t'attendre à rencontrer et à devoir traiter comme faisant
partie d'un mot ? Par ailleurs, comme je ne sais pas encore si cela a un
impact sur la recherche, est-ce que tu sais si tu peux rencontrer des
accents non pré-composés (ex. : « e + accent aigu » au lieu de « é ») ?

Cordialement,
--
Olivier Miakinen
Olivier Miakinen
2008-09-06 21:24:56 UTC
Permalink
Post by mostafa
la 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
Continuer la lecture sur narkive:
Loading...