Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

str_word_count et multibyte

2 réponses
Avatar
mostafa
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.

2 réponses

Avatar
Olivier Miakinen
Bonjour,

Le 06/09/2008 14:33, mostafa a écrit :

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
Avatar
Olivier Miakinen
Le 06/09/2008 18:56, je répondais à 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