¿Cómo codifico / decodifico entidades HTML en Ruby?

200

Estoy tratando de decodificar algunas entidades HTML, como el '&amp;lt;'devenir '<'.

Tengo una gema antigua ( html_helpers ) pero parece que la abandoné dos veces.

¿Alguna recomendación? Necesitaré usarlo en un modelo.

Kostas
fuente
66
Acabo de encontrar 'htmlentities' ( htmlentities.rubyforge.org )
Kostas
Debería especificar que consigo el código HTML de un montón de diferentes sitios y necesidad de guardarlo como texto sin formato en la base de datos
Kostas
1
Si bien la mayoría de los votos fueron para usar CGI, no lo hagas. Eso es como aprovechar todo el Soporte Activo para obtener un único método. En su lugar, use HTMLEntities, como se menciona en la respuesta seleccionada.
The Tin Man

Respuestas:

153

HTMLEntities puede hacerlo:

: 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
fuente
Zdrasti Ivailo. Gracias por tu comentario; resolvió mi problema en ¿Cómo puedo representar referencias de entidades de caracteres XML en Ruby? ¡también!
Josh Glover
44
Sí, la HTMLEntitiesgema se ocupa de casos como &aring;y &mdash;que CGI.unescapeHTMLno.
thomax
295

Para codificar los caracteres, puede usar CGI.escapeHTML:

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

Para decodificarlos, hay CGI.unescapeHTML:

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

Por supuesto, antes de eso debes incluir la biblioteca CGI:

require 'cgi'

Y si estás en Rails, no necesitas usar CGI para codificar la cadena. Ahí está el hmétodo.

<%= h 'escaping <html>' %>
Damien MATHIEU
fuente
9
Primero probé este enfoque pero no convierte entidades como "& nbsp;" dentro " ". Supongo que debería especificar que obtengo el html de varios sitios diferentes y necesito guardarlo como texto sin formato en la base de datos.
Kostas
2
Si está decodificando entidades HTML para almacenarlas como texto sin formato en una base de datos, espere que su base de datos se queje mucho de los caracteres incorrectos. Las entidades codificadas se codifican para permitir que se transfieran como texto sin formato. Decodificarlos puede, y muy probablemente lo hará, revertirlos a caracteres de bits superiores, también conocidos como binarios. Casi con toda probabilidad, podría terminar con caracteres multibyte que realmente irritarán una base de datos que espera texto sin formato. Es mejor decodificar hasta que nada cambie, luego codificar una vez para que todo esté normalizado, luego almacenarlos.
The Tin Man
1
Me he encontrado con un montón de HTML con entidades que han sido codificadas varias veces, lo que realmente hace un desastre. Echa un vistazo a la esponja vegetal ; Sus depuradores fueron diseñados para esto si no recuerdo mal.
The Tin Man
3
Hemos configurado nuestra base de datos para guardar Unicode, así que dudo que se queje. Y loofah no es lo que estoy buscando, no quiero deshacerme de las etiquetas html, no en este punto de todos modos.
Kostas
1
es 2015, unescapeHTML todavía omite algunas de las entidades como A agudo
nurettin
47

Creo que la gema Nokogiri también es una buena opción. Es muy estable y tiene una gran comunidad contribuyente.

Muestras:

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

o

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
fuente
3
@ theTinMan, sí, creo que depende de la demanda. Como puede ver a través de las discusiones en este tema, CGI.escapeHTMLtal vez no pueda resolver algunos casos. Por otro lado, si necesita un conjunto completo de soporte, estoy seguro de que Nokogiries una buena opción.
Hoang Le
66
Además, si ya está utilizando Nokogiri para un análisis HTML, no es razonable instalar otra gema solo para ese propósito. Por ejemplo, estoy usando Sanitize gem para limpiar HTML. Resulta que esta gema está usando Nokogiri debajo del capó, por lo que sería una pena no aprovechar eso. Gracias @HoangLe por el consejo!
Tomalla
1
Nota: CGI::escapeHTMLno se escapa de los caracteres alemanes como äöüß, y tal vez más ... Con Nokogiri aún no lo comprobé, pero esto sería un punto a favor.
Belleza
HTMLEntities sería una opción ligera y capaz. Uso mucho Nokogiri y, a menos que ya lo tenga cargado, iría con HTMLEntities. CGI está desactualizado.
The Tin Man
36

Para decodificar caracteres en Rails use:

<%= raw '<html>' %>

Entonces,

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

saldría

<br>
memonk
fuente
55
Sin embargo, esto solo funciona en la vista. Necesito algo que funcione en ActiveRecord también.
Kostas
3
Acabo de probar en el depurador - raw '& lt br & gt' ==> '& lt br & gt'.
Will Tomlins
13
#rawNo decodifica nada. Le dice a la vista que no codifique la cadena. Lo hace envolviendo la cadena en a ActiveSupport::SafeBuffer, que a su vez tiene una bandera ( html_safe?), establecida en verdadero. La vista usa este indicador para determinar que la cadena se puede inyectar directamente en el HTML sin escapar. Me gusta pensar html_safeque el programador indica que la cadena en cuestión ya se ha escapado correctamente.
Moxley Stratton
9

Si no desea agregar una nueva dependencia solo para hacer esto (como HTMLEntities) y ya lo está utilizando Hpricot, puede escapar y no escapar por usted. Maneja mucho más que CGI:

Hpricot.uxs "foo&nbsp;b&auml;r"
=> "foo bär"
Jason L Perry
fuente
55
Nota para las personas que miran esto ahora: Hpricot ya no se mantiene.
SamStephens
2
Utilice Nokogiri , que es el estándar de facto para el análisis XML / HTML, en lugar de Hpricot.
The Tin Man
0

Puedes usar htmlasciigema:

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

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

<%= CGI.unescapeHTML(str).html_safe %>
Usman
fuente
Creo que al agregar html_safe en cualquier texto ingresado por el usuario, le está diciendo a la opinión que es seguro cuando es posible que no lo sea. Esto pondría a sus usuarios en riesgo cuando carguen esa vista.
user1515295
No sé por qué tan negativo. Intenté todas las soluciones en esta pregunta. Solo que esto funciona bien. Sobre HTML seguro, el usuario QUIERE renderizar el HTML, luego HTML_SAFE es correcto.
Diego Somar