OK, nous allons essayer de recréer mb_convert_case
le plus près possible mais seulement changer le premier caractère de chaque mot
la partie pertinente de mb_convert_case
mise en œuvre est la suivante:.
int mode = 0;
for (i = 0; i < unicode_len; i+=4) {
int res = php_unicode_is_prop(
BE_ARY_TO_UINT32(&unicode_ptr[i]),
UC_MN|UC_ME|UC_CF|UC_LM|UC_SK|UC_LU|UC_LL|UC_LT|UC_PO|UC_OS, 0);
if (mode) {
if (res) {
UINT32_TO_BE_ARY(&unicode_ptr[i],
php_unicode_tolower(BE_ARY_TO_UINT32(&unicode_ptr[i]),
_src_encoding TSRMLS_CC));
} else {
mode = 0;
}
} else {
if (res) {
mode = 1;
UINT32_TO_BE_ARY(&unicode_ptr[i],
php_unicode_totitle(BE_ARY_TO_UINT32(&unicode_ptr[i]),
_src_encoding TSRMLS_CC));
}
}
}
En fait, cela fait comme suit:
- Set
mode
-0
. mode
déterminera si nous sommes dans le premier caractère d'un mot. Si c'est 0
, nous sommes, sinon, nous ne le sommes pas.
- Effectue une itération sur les caractères de la chaîne.
- Déterminez le type de caractère.
- Définissez
res
à 1
s'il s'agit d'un caractère de mot. Plus précisément, définissez-le sur 1
s'il a la propriété "Marquer, Pas d'espacement", "Marque, Enveloppe", "Autre, Format", "Lettre, Modificateur", "Symbole, Modificateur", "Lettre, Majuscules", "Lettre, Minuscule", "Lettre, Titlecase", "Ponctuation, Autre" ou "Autre, Surrogate". Curieusement, "Lettre, Autre" n'est pas inclus.
- Si nous ne sommes pas au début d'un mot
- Si nous sommes à un caractère de mot, le convertir en minuscules - ce que nous ne voulons pas.
- Sinon, nous ne sommes pas à un caractère de mot, et nous avons mis
mode
à 0
pour signaler que nous passons au début d'un mot.
- Si nous sommes au beggining d'un mot et nous avons en effet un caractère de mot
- Convertir ce personnage à titre
cas
- Signal nous ne sommes plus au début d'un mot.
L'extension mbstring ne semble pas exposer les propriétés de caractère. Cela nous laisse un problème, car nous n'avons pas un bon moyen de déterminer si un caractère possède l'une des 10 propriétés pour lesquelles mb_convert_case
teste.
Heureusement, unicode character properties in regex peut nous sauver ici.
Une reproduction fidèle de mb_convert_case
avec la conversion en minuscules problématique devient:
function mb_convert_case_utf8_variation($s) {
$arr = preg_split("//u", $s, -1, PREG_SPLIT_NO_EMPTY);
$result = "";
$mode = false;
foreach ($arr as $char) {
$res = preg_match(
'/\\p{Mn}|\\p{Me}|\\p{Cf}|\\p{Lm}|\\p{Sk}|\\p{Lu}|\\p{Ll}|'.
'\\p{Lt}|\\p{Sk}|\\p{Cs}/u', $char) == 1;
if ($mode) {
if (!$res)
$mode = false;
}
elseif ($res) {
$mode = true;
$char = mb_convert_case($char, MB_CASE_TITLE, "UTF-8");
}
$result .= $char;
}
return $result;
}
Test:
echo mb_convert_case_utf8_variation("HETÁ1200 Ááxt ítring uii");
donne:
HETÁ1200 Ááxt Ítring Uii
merci. c'est ingénieux! vraiment apprécier votre explication aussi. :) – Lyon