Comment encoder / décoder des entités HTML dans Ruby?

200

J'essaie de décoder certaines entités HTML, comme '&amp;lt;'devenir '<'.

J'ai un vieux bijou ( html_helpers ) mais il semble avoir été abandonné deux fois.

Des recommandations? Je devrai l'utiliser dans un modèle.

Kostas
la source
6
Je viens de trouver 'htmlentities' ( htmlentities.rubyforge.org )
Kostas
Je dois préciser que j'obtiens le code HTML à partir d'un tas de sites différents et que je dois l'enregistrer en texte brut dans la base de données
Kostas
1
Bien que la plupart des votes soient allés à l'utilisation de CGI, ne le faites pas. C'est comme tirer tout le support actif pour obtenir une seule méthode. Utilisez plutôt HTMLEntities, comme indiqué dans la réponse sélectionnée.
The Tin Man

Réponses:

153

Les HTMLEntities peuvent le faire:

: jmglov@laurana; sudo gem install htmlentities
Successfully installed htmlentities-4.2.4
: jmglov@laurana;  irb
irb(main):001:0> require 'htmlentities'
=> []
irb(main):002:0> HTMLEntities.new.decode "&iexcl;I&#39;m highly&nbsp;annoyed with character references!"
=> "¡I'm highly annoyed with character references!"
Ivailo Bardarov
la source
Zdrasti Ivailo. Merci pour votre commentaire; il a résolu mon problème sur Comment puis-je rendre les références d'entité de caractère XML dans Ruby? ainsi que!
Josh Glover
4
Oui, la HTMLEntitiesgemme traite des cas tels que &aring;et &mdash;qui CGI.unescapeHTMLne le font pas.
thomax
295

Pour encoder les caractères, vous pouvez utiliser CGI.escapeHTML:

string = CGI.escapeHTML('test "escaping" <characters>')

Pour les décoder, il y a CGI.unescapeHTML:

CGI.unescapeHTML("test &quot;unescaping&quot; &lt;characters&gt;")

Bien sûr, avant cela, vous devez inclure la bibliothèque CGI:

require 'cgi'

Et si vous êtes dans Rails, vous n'avez pas besoin d'utiliser CGI pour encoder la chaîne. Voilà la hméthode.

<%= h 'escaping <html>' %>
Damien MATHIEU
la source
9
J'ai d'abord essayé cette approche mais elle ne transforme pas des entités comme "& nbsp;" en "". Je suppose que je devrais spécifier que j'obtiens le code HTML à partir d'un tas de sites différents et que je dois l'enregistrer en texte brut dans la base de données.
Kostas
2
Si vous décodez des entités HTML pour le stockage en texte brut dans une base de données, attendez-vous à ce que votre base de données se plaigne beaucoup des mauvais caractères. Les entités encodées sont encodées pour leur permettre de transférer en texte brut. Leur décodage peut, et très probablement, les ramener en caractères de l'ensemble de bits supérieur, binaire AKA. Presque aussi probablement, vous pourriez vous retrouver avec des caractères multi-octets qui irrite vraiment une base de données qui attend du texte brut. Il vaut mieux décoder jusqu'à ce que rien ne change, puis encoder une fois pour que tout soit normalisé, puis les stocker.
The Tin Man
1
J'ai rencontré beaucoup de HTML avec des entités qui ont été encodées plusieurs fois, ce qui a vraiment gâché les choses. Découvrez le luffa ; Ses épurateurs ont été conçus pour cela si je me souviens bien.
The Tin Man
3
Nous avons configuré notre base de données pour enregistrer Unicode, donc je doute qu'il se plaindra du tout. Et le loofah n'est pas ce que je cherche, je ne veux pas me débarrasser des balises html - pas à ce stade de toute façon.
Kostas
1
nous sommes en 2015, unescapeHTML omet encore certaines des entités telles que A aigu
nurettin
47

Je pense que le joyau de Nokogiri est également un bon choix. Il est très stable et possède une énorme communauté de contribution.

Échantillons:

a = Nokogiri::HTML.parse "foo&nbsp;b&auml;r"    
a.text 
=> "foo bär"

ou

a = Nokogiri::HTML.parse "&iexcl;I&#39;m highly&nbsp;annoyed with character references!"
a.text
=> "¡I'm highly annoyed with character references!"
Hoang Le
la source
3
@theTinMan, oui, je pense que cela dépend de la demande. Comme vous pouvez le voir à travers les discussions de cette rubrique, vous ne pourrez peut- CGI.escapeHTMLêtre pas résoudre certains cas. D'un autre côté, si vous avez besoin d'un support complet, je suis sûr que Nokogiric'est un bon choix.
Hoang Le
6
De plus, si vous utilisez déjà Nokogiri pour une analyse HTML, il est déraisonnable d'installer un autre joyau uniquement à cette fin. Par exemple, j'utilise Sanitize gem pour nettoyer le HTML. Il s'avère que ce joyau utilise Nokogiri sous le capot et il serait donc dommage de ne pas en profiter. Merci @HoangLe pour le conseil!
Tomalla
1
Remarque: CGI::escapeHTMLn'échappe pas aux personnages allemands comme äöüß, et peut-être plus ... Avec Nokogiri, je n'ai pas encore vérifié, mais ce serait un avantage.
Beauté
HTMLEntities serait un choix léger et capable. J'utilise beaucoup Nokogiri et, sauf si je l'ai déjà chargé, j'irais avec HTMLEntities. CGI est obsolète.
The Tin Man
36

Pour décoder des caractères dans Rails, utilisez:

<%= raw '<html>' %>

Alors,

<%= raw '&lt;br&gt;' %>

sortirait

<br>
memonk
la source
5
Cela ne fonctionne cependant que dans la vue. J'ai aussi besoin de quelque chose qui fonctionne dans ActiveRecord.
Kostas
3
Vient de tester dans le débogueur - raw '& lt br & gt' ==> '& lt br & gt'.
Will Tomlins
13
#rawne décode rien. Il indique à la vue de ne pas coder la chaîne. Pour ce faire, il encapsule la chaîne dans un ActiveSupport::SafeBuffer, qui à son tour a un indicateur ( html_safe?), défini sur true. La vue utilise cet indicateur pour déterminer que la chaîne peut être injectée directement dans le code HTML sans être échappée. J'aime à considérer html_safecomme une indication par le programmeur que la chaîne en question a déjà été correctement échappée.
Moxley Stratton
9

Si vous ne voulez pas ajouter une nouvelle dépendance juste pour faire cela (comme HTMLEntities) et que vous l'utilisez déjà Hpricot, elle peut à la fois s'échapper et s'échapper pour vous. Il gère bien plus que CGI:

Hpricot.uxs "foo&nbsp;b&auml;r"
=> "foo bär"
Jason L Perry
la source
5
Remarque pour les personnes qui regardent cela maintenant - Hpricot n'est plus maintenu.
SamStephens
2
Utilisez Nokogiri , qui est la norme de facto pour l'analyse XML / HTML, au lieu de Hpricot.
The Tin Man
0

Vous pouvez utiliser htmlasciigem:

Htmlascii.convert string
kartouch
la source
-5
<% str="<h1> Test </h1>" %>

result: &lt; h1 &gt; Test &lt; /h1 &gt;

<%= CGI.unescapeHTML(str).html_safe %>
Usman
la source
Je pense qu'en ajoutant html_safe sur n'importe quel texte saisi par l'utilisateur, vous dites à la vue qu'il est sûr lorsqu'il est possible qu'il ne l'est pas. Cela mettrait vos utilisateurs en danger lorsqu'ils chargent cette vue.
user1515295
Je ne sais pas pourquoi si négatif. J'ai essayé toutes les solutions dans cette question. Seulement cela fonctionne bien. À propos de HTML safe, l'utilisateur VEUT rendre le HTML, alors HTML_SAFE est correct.
Diego Somar