Como codificar / decodificar entidades HTML no Ruby?

200

Estou tentando decodificar algumas entidades HTML, como '&amp;lt;'tornar-se '<'.

Eu tenho uma jóia antiga ( html_helpers ), mas parece ter sido abandonada duas vezes.

Alguma recomendação? Vou precisar usá-lo em um modelo.

Kostas
fonte
6
Acabei de encontrar 'htmlentities' ( htmlentities.rubyforge.org )
Kostas
Eu deveria especificar que eu recebo o html de um monte de sites diferentes e necessidade de salvá-lo como texto simples no banco de dados
Kostas
1
Enquanto a maioria dos votos foi para o uso de CGI, não. É como usar todo o Suporte Ativo para obter um único método. Em vez disso, use HTMLEntities, conforme mencionado na resposta selecionada.
the Tin Man

Respostas:

153

HTMLEntities pode fazer isso:

: 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
fonte
Zdrasti Ivailo. Obrigado por seu comentário; resolveu meu problema em Como posso renderizar referências de entidade de caracteres XML no Ruby? também!
21711 Josh Glover
4
Sim, a HTMLEntitiesgema lida com casos como &aring;e &mdash;quais CGI.unescapeHTMLnão.
Thomax
295

Para codificar os caracteres, você pode usar CGI.escapeHTML:

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

Para decodificá-los, existe CGI.unescapeHTML:

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

Obviamente, antes disso, você precisa incluir a biblioteca CGI:

require 'cgi'

E se você estiver no Rails, não precisará usar CGI para codificar a string. Existe o hmétodo.

<%= h 'escaping <html>' %>
Damien MATHIEU
fonte
9
Tentei essa abordagem primeiro, mas ela não transforma entidades como "& nbsp;" para dentro " ". Acho que devo especificar que recebo o html de vários sites diferentes e preciso salvá-lo como texto sem formatação no banco de dados.
Kostas
2
Se você estiver decodificando entidades HTML para armazenamento como texto sem formatação em um banco de dados, espere que o banco de dados faça muitas reclamações sobre caracteres incorretos. As entidades codificadas são codificadas para permitir a transferência como texto sem formatação. Decodificá-los pode, e provavelmente irá, revertê-los para caracteres com conjunto de bits superior, binário AKA. É quase provável que você possa acabar com caracteres multibyte, o que realmente irritará um banco de dados que está esperando texto sem formatação. É melhor decodificar até que nada mude, depois codifique uma vez para que tudo seja normalizado e depois armazene-o.
the Tin Man
1
Eu encontrei muito HTML com entidades que foram codificadas várias vezes, realmente fazendo uma bagunça. Confira bucha ; Seus lavadores foram projetados para isso, se bem me lembro.
the Tin Man
3
Definimos nosso banco de dados para salvar Unicode, então duvido que ele se queixe. E bucha não é o que estou procurando, não quero me livrar das tags html - não neste momento, de qualquer maneira.
Kostas
1
é 2015, o unescapeHTML ainda omite algumas das entidades como A aguda
nurettin
47

Eu acho que a jóia Nokogiri também é uma boa escolha. É muito estável e tem uma enorme comunidade contribuinte.

Amostras:

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
fonte
3
@theTinMan, sim, acho que depende da demanda. Como você pode ver nas discussões deste tópico, CGI.escapeHTMLtalvez não consiga resolver alguns casos. Por outro lado, se você precisar de um conjunto completo de suporte, tenho certeza de que Nokogirié uma boa escolha.
Hoang Le
6
Além disso, se você já estiver usando o Nokogiri para análise de HTML, não é razoável instalar outra jóia apenas para esse fim. Por exemplo, estou usando o Sanitize gem para limpar o HTML. Acontece que esta gema está usando Nokogiri sob o capô e, portanto, seria uma pena não se aventurar nisso. Obrigado @HoangLe pela dica!
Tomalla
1
Nota: CGI::escapeHTMLnão escapa caracteres alemães como äöüß, e talvez mais ... Com Nokogiri ainda não verifiquei, mas esse seria um ponto positivo.
Beleza #
HTMLEntities seria uma escolha leve e capaz. Eu uso muito o Nokogiri e, a menos que já o tenha carregado, eu usaria o HTMLEntities. O CGI está desatualizado.
the Tin Man
36

Para decodificar caracteres no Rails, use:

<%= raw '<html>' %>

Assim,

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

produziria

<br>
memonk
fonte
5
Isso funciona apenas na visualização. Também preciso de algo que funcione no ActiveRecord.
Kostas
3
Acabei de testar no depurador - raw '& lt br & gt' ==> '& lt br & gt'.
Will Tomlins
13
#rawnão decodifica nada. Diz à exibição para não codificar a sequência. Isso é feito envolvendo a string em a ActiveSupport::SafeBuffer, que por sua vez possui uma flag ( html_safe?), definida como true. A visualização usa esse sinalizador para determinar que a cadeia pode ser injetada diretamente no HTML sem ser escapada. Eu gosto de pensar html_safecomo uma indicação do programador de que a string em questão já foi escapada corretamente.
Moxley Stratton #
9

Se você não deseja adicionar uma nova dependência apenas para fazer isso (como HTMLEntities) e já está usando Hpricot, ela pode escapar e não escapar para você. Ele lida com muito mais do que CGI:

Hpricot.uxs "foo&nbsp;b&auml;r"
=> "foo bär"
Jason L Perry
fonte
5
Nota para as pessoas que estão vendo isso agora - o Hpricot não é mais mantido.
precisa saber é o seguinte
2
Use Nokogiri , que é o padrão para análise XML / HTML, em vez de Hpricot.
the Tin Man
0

Você pode usar htmlasciigema:

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

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

<%= CGI.unescapeHTML(str).html_safe %>
Usman
fonte
Penso que, ao adicionar html_safe em qualquer texto inserido pelo usuário, você estará dizendo que é seguro quando é possível que não seja seguro. Isso colocaria seus usuários em risco quando eles carregassem essa exibição.
user1515295
Não sei por que é tão negativo. Eu tentei todas as soluções nesta pergunta. Só isso funciona bem. Sobre o HTML seguro, o usuário QUER renderizar o HTML, então HTML_SAFE está correto.
Diego Somar 16/09