PHP a la fonction ucwords(), qui permet des délimiteurs personnalisés. Cela fonctionne bien et transformera my test string en My Test String sans problème.

Prenons l'exemple suivant : je veux créer un tag de joueur 2009 super génial.

$gamerTag = 'xxx_l33t_xxx'; // Not yet epic. 
echo ucwords($gamerTag,"x"); // want it to return 'xXx_l33t_xXx'

J'aurais supposé que les chaînes délimiteraient la casse et mettront à jour le deuxième x dans chaque cas, en ignorant le troisième, car à ce stade, celui du milieu ne correspondrait plus à notre délimiteur.

Cependant, cela renvoie en fait XxX_l33t_xXx, car il mettra automatiquement en majuscule la première lettre de la chaîne.

Je sais qu'il existe d'autres méthodes pour le faire (strsplit() boucles de tableau et pregreplace avec une recherche inversée me viennent à l'esprit), mais ma question principale devient la suivante :

Existe-t-il un moyen de délimiter ucwords() de manière à ne pas automatiquement mettre en majuscule le premier caractère de la chaîne ?

php
-1
Aaron Morefield 24 févr. 2020 à 13:47

1 réponse

Meilleure réponse

Le comportement interne est malheureusement que le premier caractère de la chaîne sera toujours converti en majuscule, quels que soient les délimiteurs que vous transmettez.

En creusant dans la source PHP, voici l'implémentation de ucwords :

*r = toupper((unsigned char) *r);

for (r_end = r + Z_STRLEN_P(return_value) - 1; r < r_end; ) {
    if (mask[(unsigned char)*r++]) {
        *r = toupper((unsigned char) *r);
    }
}

Depuis https://github.com/php /php-src/blob/master/ext/standard/string.c#L2651

Ici, r est la valeur de retour et mask est un tableau de caractères des caractères de délimitation. Le premier appel à toupper (en dehors de la boucle) signifie qu'il n'y a aucun moyen d'empêcher la conversion du premier caractère.

Parce que cela est fait, cela signifie que le deuxième caractère n'est pas converti, car il est maintenant précédé de X, et non de x. Le troisième caractère est géré "correctement".

Cela peut en fait provoquer un comportement en cascade étrange, car la valeur de retour est itérée pendant qu'elle est modifiée :

php > echo ucwords('aaa', 'A');
AAA

La chaîne initiale ne contient nulle part le caractère de délimitation, mais le résultat est entièrement en majuscules.

Comme mentionné dans un commentaire, il existe un bogue PHP ouvert pour refléter ce comportement dans la documentation ici : https://bugs.php.net/bug.php?id=78393

2
iainn 24 févr. 2020 à 12:39