mageekblog - Mot-clé - PHP 5.3.4Le blog personnel de Frédéric Hardy. Au menu, PHP, agilité, FreeBSD, cuisine et photographies.2021-12-02T08:20:54+01:00Frédéric Hardyurn:md5:26874ca5b8cd4cac8d08b0e68e64f63aDotclearSupprimer les accents d'une chaîne de caractères et la passer en lowerCamelCase en PHPurn:md5:8d075b8da28640ec0dde7936b7aac4792010-12-23T20:30:00+01:002010-12-24T09:58:03+01:00mageekguyPHPaccentsintllowerCamelCasePHPPHP 5.3.4Unicode<p>Dans le cadre de mon travail, je viens d'être confronté à une problématique intéressante, dans le sens où elle m'a fait utiliser une fonctionnalité de PHP 5.3 que je n'avais encore jamais eu l'occasion d'utiliser, à savoir <a href="http://fr.php.net/manual/fr/book.intl.php"><code>intl</code></a>.</p>
<p>J'ai été en effet obligé de trouver un code <a href="http://www.php.net/">PHP</a> permettant de transformer la chaîne de caractères <q>Équipe médicale principale</q> en <q>equipeMedicalePrincipale</q>.</p>
<p>Le problème peut sembler trivial, et pourtant, il n'est pas simple à régler.</p>
<p>Il est possible de le décomposer en quatre étapes :</p>
<ol><li>Passage en casse basse de la première lettre.</li>
<li>Suppression des accents.</li>
<li>Passage en casse haute de toutes les lettres précédées d'un espace.</li>
<li>Suppression des espaces blancs.</li>
</ol>
<p>Et si les étapes 1, 3 et 4 sont relativement simple, l'étape 2 est quand à elle beaucoup plus délicate à solutionner.</p> <p>Pour la première étape, un appel à la fonction <code><a href="http://fr.php.net/manual/fr/function.lcfirst.php">lcfirst()</a></code> sur la chaîne de caractères considérée résout le problème très efficacement.</p>
<p>Le passage en casse haute de toutes les lettres précédées d'un espace, qui correspond à l'étape 3, est déjà moins évident.</p>
<p><a href="http://www.php.net">PHP</a> dispose de la fonction inverse de <code><a href="http://fr.php.net/manual/fr/function.lcfirst.php">lcfirst()</a></code>, à savoir <code><a href="http://fr.php.net/manual/fr/function.ucfirst.php">ucfirst()</a></code>.</p>
<p>Il reste donc à localiser les lettres sur lesquelles il faut l'appliquer.</p>
<p>Pour cela, <a href="http://fr.php.net/manual/fr/function.preg-replace.php"><code>preg_replace()</code></a> est notre amie, puisque cette fonction est capable d'exécuter une fonction sur chaque remplacement, via le drapeau <q><code>e</code></q>.</p>
<p>Il suffit donc de lui demander de remplacer tous les espaces par la lettre qui le suit en casse haute, de la manière suivante :</p>
<blockquote><pre><code><?php $string = preg_replace('/\s+(.)/ue', 'ucfirst(\'\\1\')', $string); ?></code></pre></blockquote>
<p>Ma chaîne étant au format <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a>, j'ai pris soins d'activer le drapeau <q><code>u</code></q> en plus de <q><code>e</code></q> afin que l'encodage soit pris en compte par la fonction.</p>
<p>Les plus attentifs auront certainement remarqué que nous venons de résoudre simultanément les problèmes posés par les étapes 3 et 4.</p>
<p>Il ne reste donc plus qu'à trouver une solution pour le problème posé par l'étape 2.</p>
<p>En parcourant Internet, j'ai trouvé <a href="http://fr.w3support.net/index.php?db=so&id=249087">différentes</a> <a href="http://fr.php.net/manual/fr/normalizer.normalize.php#92592">solutions</a>, <a href="http://stackoverflow.com/questions/1017599/how-do-i-remove-accents-from-characters-in-a-php-string">plus</a> ou <a href="http://www.commentcamarche.net/faq/8063-supprimer-les-accents-avec-php">moins</a> <a href="http://www.comscripts.com/sources/php.remove-accents.4.html">immondes</a>, et les plus intéressantes étaient basées sur <a href="http://fr.php.net/manual/fr/book.intl.php"><code>intl</code></a>.</p>
<p>Mon contexte de mise en œuvre étant strictement limité au français, j'ai décidé de me baser sur ces dernières en les simplifiant fortement.</p>
<p>La logique de fonctionnement est basée sur la <a href="http://fr.wikipedia.org/wiki/Normalisation_Unicode">normalisation</a> des chaînes <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a>, qui consiste, en très résumé, à remplacer, par exemple, le caractère <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a> <q>é</q> par la combinaison des caractères <q>e</q> et <q> ́</q> dans la chaîne considérée.</p>
<p>Une fois cela réalisé, il ne suffit donc plus que de supprimer les caractères <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a> ajoutant l'accentuation pour obtenir une chaîne sans le moindre accent.</p>
<p>Pour cela, <a href="http://fr.php.net/manual/fr/function.preg-replace.php"><code>preg_replace()</code></a> est une nouvelle fois mis à contribution, via les <a href="http://fr.php.net/manual/fr/regexp.reference.unicode.php">propriétés</a> des caractères <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a>.</p>
<p>Une fois tout cela combiné, on obtient le magnifique code suivant :</p>
<blockquote><pre><code><?php $string = lcfirst(preg_replace('/\s+(.)/ue', 'ucfirst(\'\\1\')', preg_replace('@\pM@u', '', \normalizer::normalize(trim($string), Normalizer::FORM_D)))); ?></code></pre></blockquote>
<p>Et si l'on aime le beau code, comme moi, il est possible de pousser l'esthétique jusqu'à cela :</p>
<blockquote><pre><code><?php $string = preg_replace(array('@\pM@u', '/^(.)/ue', '/\s+(.)/ue'), array('', 'lcfirst(\'\\1\')', 'ucfirst(\'\\1\')'), \normalizer::normalize(trim($string), Normalizer::FORM_D)); ?></code></pre></blockquote>
<p><ironie>Finalement, <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a>, ça peut servir !</ironie></p>
<p>[MAJ] Suite à la parution de ce qui précède, il m'a été proposé d'autres solutions, la plupart reposant sur <a href="http://fr.php.net/manual/fr/book.iconv.php"><code>iconv</code></a>.</p>
<p>Dans un premier temps, je ne les avais pas prise en compte, car je pensais que cette extension n'était pas native au langage, au contraire de <a href="http://fr.php.net/manual/fr/book.intl.php"><code>intl</code></a>, ce qui aurait été un problème dans mon contexte de mise en œuvre.</p>
<p>Or, après <a href="http://fr.php.net/manual/fr/iconv.installation.php">vérification</a>, <a href="http://fr.php.net/manual/fr/book.iconv.php"><code>iconv</code></a> est bien livrée en standard avec <a href="http://www.php.net">PHP</a>, et elle a l'avantage de permettre la gestion de tous les alphabets, puisqu'elle permet la conversion d'une chaîne de caractère <a href="http://fr.wikipedia.org/wiki/Unicode">Unicode</a> vers l'<abbr title="American Standard Code for Information Interchange"><a href="http://fr.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange">ASCII</a></abbr>.</p>
<p>Voici donc une solution basée sur cette extension, conçue à partir de <a href="http://pastie.org/1402580">la proposition</a> de <a href="http://blog.yoda-bzh.net/">Maître Yoda</a> :</p>
<blockquote><pre><code><?php $string = lcfirst(preg_replace('/\s+/u', '', ucwords(strtolower(iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', trim($string)))))); ?></code></pre></blockquote>http://blog.mageekbox.net/?post/2010/12/23/Supprimer-les-accents-d-une-cha%C3%AEne-de-caract%C3%A8re-et-la-passer-en-lowerCamelCase-en-PHP#comment-formhttp://blog.mageekbox.net/?feed/atom/comments/222PHP 5.3.4 est disponible !urn:md5:57633fbc7b6f019191287cfc3ae7b1692010-12-10T08:00:00+01:002010-12-10T16:47:12+01:00mageekguyPHPhtmlentitieshtmlspecialcharsPCREPHP 5.3.4SQLite <p>Une nouvelle version de maintenance de la branche 5.3 du langage est disponible depuis ce matin.</p>
<p>Il ne faut donc en attendre aucune nouveauté majeures, même si plus d'une centaine de bugs ont été résolus et qu'elle apporte quelques aménagements visant à améliorer le confort d'utilisation du langage.</p>
<p>Les fonctions <code><a href="http://fr.php.net/manual/fr/function.htmlentities.php">htmlentities()</a></code> et <a href="http://fr.php.net/manual/fr/function.htmlspecialchars.php"><code>htmlspecialchars()</code></a> dispose par exemple maintenant d'un meilleur support d'<a href="http://en.wikipedia.org/wiki/Unicode">Unicode</a>, et des optimisations ont été effectuées à différents niveaux pour améliorer les performances.</p>
<p>Il faut cependant noté que le gain est très loin d'être aussi significatif que dans le cas de la version en cours de développement disponible dans le <a href="http://svn.php.net/viewvc/php/php-src/trunk/">trunk</a>.</p>
<p>Par ailleurs, <a href="http://www.sqlite.org/">SQLite</a> est passé en version 3.7.3 et <a href="http://www.pcre.org/"><abbr title="Perl Compatible Regular Expressions">PCRE</abbr></a> en version 8.10.</p>
<p>Il n'y a donc rien de bien transcendant à se mettre sous la dent avec cette version, les nouveautés étant réservées à <a href="http://blog.mageekbox.net/?post/2010/11/21/Mort-de-PHP6-250-jours">PHP 5.4</a>, mais vu le nombre de correctifs qu'elle apporte, Je ne peux que vous conseiller d'effectuer la migration, afin de gagner en stabilité, notamment si vous êtes encore en <a href="http://php.net/migration53">version 5.2</a>.</p>
<p>Pour ceux désirant des informations supplémentaires ou plus détaillées, je les invite à lire le <a href="http://www.php.net/ChangeLog-5.php#5.3.4">Changelog</a>, qui regorge de détails pouvant être précieux en fonction du contexte d'utilisation du langage.</p>
<p>Comme d'habitude, les sources de cette nouvelle versions sont librement <a href="http://www.php.net/downloads.php">téléchargeables</a> et les binaires destinés à Windows sont <a href="http://windows.php.net/download/">disponibles</a>.</p>
<p>Il faut de plus noter qu'une version de maintenance pour la branche 5.2 dénommée 5.2.15 est également <a href="http://www.php.net/archive/2010.php#id2010-12-09-1">disponible</a> depuis aujourd'hui et intègre une partie des corrections et des modifications apportées à la branche 5.3, ainsi que d'autres corrections.</p>http://blog.mageekbox.net/?post/2010/12/10/PHP-5.3.4-est-disponible-%21#comment-formhttp://blog.mageekbox.net/?feed/atom/comments/217