Encoder des accents sans toucher aux balises HTML

…Et surtout sans tableau de conversion!
Cette opération (à priori très simple) peut poser problème, notamment à cause de l’encodage des caractères.

Faisons le test avec une chaîne de caractères contenant des balises HTML et des accents.

$chaine = "Le <em>péHpé</em> çaÿ <strong>biên</strong>.";

Nous souhaitons obtenir la chaîne suivante:

Le <em>p&eacute;Hp&eacute;</em> &ccedil;a&yuml; <strong>bi&ecirc;n</strong>.

Commençons donc par faire appel à la fonction htmlentities. Pour rappel, cette fonction « convertit tous les caractères éligibles en entités HTML ». Donc les accents seront effectivement encodés… ainsi que les balises HTML (contrairement à la fonction htmlspecialchars qui elle n’aurait pas encodé les accents). N’oubliez pas de préciser le « jeu de caractères », exemple si vous êtes comme moi en UTF-8:

//encodage des accents ET des balises
 echo htmlentities($chaine, ENT_NOQUOTES, 'UTF-8');

Heureusement il existe une fonction capable de faire l’inverse, sans toucher aux accents: htmlspecialchars_decode. Nous obtenons donc:

echo htmlspecialchars_decode(htmlentities($chaine, ENT_NOQUOTES, 'UTF-8'));

Et le tour est joué!

Et si je veux obtenir l’effet inverse?

Là c’est plus simple:

//convertir les &eacute; en é sans toucher aux balises HTML
echo html_entity_decode($chaine, ENT_NOQUOTES, "UTF-8");
15 commentaires
  1. Akemi dit :

    Merci beaucoup pour cette astuce, elle m’a rendue grand service !

  2. Elg dit :

    YES merci beaucoup, j’ai galéré longtemps sur plein de forums et de sites, et voilà, cette astuce a marché 🙂

  3. Ben dit :

    ravi d’avoir pu aider 🙂

  4. Elg dit :

    Ah, je reviens : une remarque, ça marche pour les accents, mais pas les apostrophes ni le signe euro.

    Texte original :

    « Cuisine équipée d’un bloc évier avec plaques électriques et réfrigérateur, installation pour lave linge.
    Loyer mensuel 325€.Dépôt de garantie 325€. »

    Texte obtenu sans ta méthode (brut) :

    « Cuisine �quip�e d�un bloc �vier avec plaques �lectriques et r�frig�rateur, installation pour lave linge.
    Loyer mensuel 325�.D�p�t de garantie 325�. »

    Texte obtenu avec ta méthode :

    « Cuisine équipée d�un bloc évier avec plaques électriques et réfrigérateur, installation pour lave linge.
    Loyer mensuel 325�.Dépôt de garantie 325�. »

    C’est mieux mais pas parfait 🙂 Est-il possible de corriger les derniers caractères?

  5. Ben dit :

    si ton document est encodé en utf-8, cela fonctionne parfaitement.
    – l’apostrophe est transformée en &rsquo;
    – le symbole Euro est transformé en &euro;

  6. Elg dit :

    Hélas non. C’est une page externe que je récupère, et elle est encodée en iso-8859-15. C’est bien le problème. Je suis en train de fouiller partout pour trouver comment encoder correctement les derniers caractères.

  7. Ben dit :

    tu peux donc utiliser:
    echo htmlspecialchars_decode(htmlentities($chaine, ENT_NOQUOTES, ‘ISO-8859-1’));

    doc ici:
    http://fr.php.net/manual/fr/function.htmlentities.php

  8. Elg dit :

    Merci de ta réponse. J’avais déjà essayé avec cette méthode, que j’avais trouvée sur la même page, mais hélas toujours les � à la place des € et des apostrophes. Même résultat. Je continue de chercher, mais avec de moins en moins d’espoir…

  9. Elg dit :

    Me revoilà. Un peu tard, mais j’ai une solution. En fait c’est un bricolage : ne pouvant pas réussir à importer correctement la page, j’ai fait un petit script analysant le caractère précédant chaque �. Si c’est un chiffre ou un espace, alors le � est probablement un € et je le remplace. Si c’est une lettre, alors le � est probablement une apostrophe.

    Voilà le script (avec jQuery, mais faisable en PHP ou autre) :

    $.each(texte, function(index, value){ /* Analyse le texte, lettre par lettre */
    if(value== »� »){
    prevChar = texte.charAt(index-1);

    if( prevChar== » « ){ /* Le caractère précédent est un espace, donc le caractère mystère est probablement un euro */
    texte = texte.replace(« � », »€ »);
    } else {
    prevChar = parseInt(prevChar);
    if( prevChar>-1 && prevChar <10 ) { /* Le caractère précédent est un chiffre, donc le caractère mystère est probablement un euro */
    texte = texte.replace("�","€");
    } else {
    texte = texte.replace("�","'"); /* sinon c'est probablement une apostrophe */
    }
    }
    }
    });

    Et voilà le texte correctement importé 🙂

  10. Ludovi dit :

    Impossible de trouver un tool en ligne qui propose la simple option d’encoder sans toucher au HTML.

  11. catou dit :

    super !!! enfin !!! apres avoir cherché des heures, tu nous offres LA solution !!!

  12. swat dit :

    Mieux vaut tard que jamais !!
    @ELG -> pour résoudre ton problème sans javascript :
    htmlentities($chaine, ENT_QUOTES, ‘UTF-8’);
    Remplace ENT_NOQUOTES par ENT_QUOTES

  13. I loved as much as you’ll receive carried out right here. The sketch is attractive, your authored subject matter stylish. nonetheless, you command get got an shakiness over that you wish be delivering the following. unwell unquestionably come further formerly again since exactly the same nearly very often inside case you shield this increase.

Laisser une réponse