Come posso codificare / decodificare entità HTML in Ruby?


200

Sto cercando di decodificare alcune entità HTML, come '&amp;lt;'diventare '<'.

Ho una vecchia gemma ( html_helpers ) ma sembra essere stata abbandonata due volte.

Qualche consiglio? Dovrò usarlo in un modello.


6
Ho appena trovato "htmlentities" ( htmlentities.rubyforge.org )
Kostas,

Dovrei specificare che ottengo l'html da un sacco di siti diversi e devo salvarlo come testo normale nel database
Kostas,

1
Mentre il maggior numero di voti è andato all'utilizzo del CGI, non farlo. È come ottenere tutto il supporto attivo per ottenere un singolo metodo. Utilizzare invece HTMLEntities, come indicato nella risposta selezionata.
Tin Man,

Risposte:


153

HTMLEntities può farlo:

: 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!"

Zdrasti Ivailo. Grazie per il tuo commento; ha risolto il mio problema su Come posso visualizzare i riferimenti alle entità di caratteri XML in Ruby? anche!
Josh Glover,

4
Sì, la HTMLEntitiesgemma si occupa di casi come &aring;e &mdash;che CGI.unescapeHTMLnon lo fanno.
Thomax,

295

Per codificare i caratteri, puoi usare CGI.escapeHTML:

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

Per decodificarli, c'è CGI.unescapeHTML:

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

Naturalmente, prima di ciò è necessario includere la libreria CGI:

require 'cgi'

E se sei in Rails, non devi usare CGI per codificare la stringa. C'è il hmetodo

<%= h 'escaping <html>' %>

9
Ho provato prima questo approccio ma non trasforma entità come "& nbsp;" in "". Immagino che dovrei specificare che ottengo l'html da un gruppo di siti diversi e che devo salvarlo come testo normale nel database.
Kostas,

2
Se stai decodificando entità HTML per l'archiviazione come testo normale in un database, allora aspettati che il tuo database si preoccupi molto dei caratteri cattivi. Le entità codificate sono codificate per consentire il trasferimento come testo normale. La decodifica può, e molto probabilmente lo farà, convertirli in caratteri a bit superiore, binario AKA. Quasi probabilmente, potresti finire con caratteri multibyte che irriteranno davvero un DB che si aspetta testo normale. È meglio decodificare fino a quando non cambia nulla, quindi codificare una volta in modo che tutto sia normalizzato, quindi memorizzarli.
Tin Man,

1
Ho incontrato molto HTML con entità che sono state codificate più volte, facendo davvero un casino di cose. Dai un'occhiata alla luffa ; I suoi lavapavimenti sono stati progettati per questo, se ricordo bene.
Tin Man,

3
Abbiamo impostato il nostro database per salvare Unicode, quindi dubito che si lamenterà affatto. E la luffa non è ciò che sto cercando, non voglio liberarmi dei tag html - non a questo punto comunque.
Kostas,

1
è il 2015, unescapeHTML omette ancora alcune entità come A acute
nurettin,

47

Penso che anche la gemma di Nokogiri sia una buona scelta. È molto stabile e ha una grande comunità che contribuisce.

Campioni:

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!"

3
@theTinMan, sì, penso che dipenda dalla domanda. Come puoi vedere attraverso le discussioni in questo argomento, CGI.escapeHTMLforse non è in grado di risolvere alcuni casi. D'altra parte, se hai bisogno di un set completo di supporto, sono sicuro che Nokogirisia una buona scelta.
Hoang Le

6
Inoltre, se stai già utilizzando Nokogiri per un po 'di analisi HTML, è irragionevole installare un altro gioiello esclusivamente a tale scopo. Ad esempio, sto usando Sanitize gem per ripulire l'HTML. Si scopre che questa gemma sta usando Nokogiri sotto il cofano e quindi sarebbe un peccato non avventurarsene. Grazie @HoangLe per l'informazione!
Tomalla,

1
Nota: CGI::escapeHTMLnon sfugge ai personaggi tedeschi come äöüß, e forse di più ... Con Nokogiri non ho ancora controllato, ma questo sarebbe un punto in più.
Beauty,

Le HTMLEntities sarebbero una scelta leggera e capace. Uso molto Nokogiri e, a meno che non lo abbia già caricato, andrei con HTMLEntities. CGI non è aggiornato.
l'Uomo di latta,

36

Per decodificare i caratteri in Rails usare:

<%= raw '<html>' %>

Così,

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

sarebbe uscita

<br>

5
Questo funziona solo nella vista però. Ho bisogno di qualcosa che funzioni anche in ActiveRecord.
Kostas,

3
Appena testato nel debugger - raw '& lt br & gt' ==> '& lt br & gt'.
Will Tomlins,

13
#rawnon decodifica nulla. Indica alla vista di non codificare la stringa. Lo fa avvolgendo la stringa in a ActiveSupport::SafeBuffer, che a sua volta ha un flag ( html_safe?), impostato su true. La vista utilizza questo flag per determinare che la stringa può essere iniettata direttamente nell'HTML senza essere salvata. Mi piace pensare html_safeal programmatore come un'indicazione che la stringa in questione è già stata correttamente salvata.
Moxley Stratton,

9

Se non vuoi aggiungere una nuova dipendenza solo per fare questo (come HTMLEntities) e stai già usando Hpricot, può sia scappare che scappare per te. Gestisce molto di più di CGI:

Hpricot.uxs "foo&nbsp;b&auml;r"
=> "foo bär"

5
Nota per le persone che lo guardano ora: Hpricot non viene più mantenuto.
SamStephens,

2
Utilizzare Nokogiri , che è lo standard defacto per l'analisi XML / HTML, anziché Hpricot.
Tin Man,


-5
<% str="<h1> Test </h1>" %>

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

<%= CGI.unescapeHTML(str).html_safe %>

Penso che aggiungendo html_safe su qualsiasi testo inserito dall'utente, stai dicendo alla vista che è sicuro quando è possibile che non sia sicuro. Ciò metterebbe a rischio i tuoi utenti quando caricheranno quella vista.
user1515295,

Non so perché sia ​​così negativo. Ho provato tutte le soluzioni in questa domanda. Solo questo funziona bene. A proposito di HTML sicuro, l'utente VUOLE rendere l'HTML, quindi HTML_SAFE è corretto.
Diego Somar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.