Как мне кодировать / декодировать HTML-объекты в Ruby?


200

Я пытаюсь декодировать некоторые объекты HTML, такие как '&amp;lt;'становление '<'.

У меня есть старый гем ( html_helpers ), но он, кажется, был заброшен дважды.

Любые рекомендации? Мне нужно будет использовать его в модели.


6
Только что нашли «htmlentities» ( htmlentities.rubyforge.org )
Костас

Я должен указать, что я получаю html с нескольких разных сайтов и должен сохранить его в виде обычного текста в базе данных
Kostas

1
Хотя большинство голосов пришло на использование CGI, не надо. Это похоже на использование всей активной поддержки, чтобы получить единый метод. Вместо этого используйте HTMLEntities, как указано в выбранном ответе.
Оловянный Человек

Ответы:


154

HTMLEntities может сделать это:

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

Здрасти Ивайло. Спасибо за ваш комментарий; это решило мою проблему: как я могу рендерить ссылки на сущности символов XML в Ruby? также!
Джош Гловер

4
Да, HTMLEntitiesдрагоценный камень имеет дело со случаями, такими как &aring;и &mdash;который CGI.unescapeHTMLне делает.
thomax

295

Для кодирования символов вы можете использовать CGI.escapeHTML:

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

Для их декодирования есть CGI.unescapeHTML:

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

Конечно, перед этим необходимо включить библиотеку CGI:

require 'cgi'

И если вы в Rails, вам не нужно использовать CGI для кодирования строки. Есть hметод.

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

9
Сначала я попробовал этот подход, но он не превращает сущности типа "& nbsp;" в "". Думаю, мне следует указать, что я получаю html с нескольких разных сайтов и мне нужно сохранить его в виде обычного текста в базе данных.
Костас

2
Если вы декодируете HTML-объекты для хранения в виде обычного текста в базе данных, ожидайте, что ваша база данных будет много жаловаться на плохие символы. Закодированные объекты кодируются, чтобы их можно было передавать в виде простого текста. Расшифровка их может и, скорее всего, вернет их к символам с верхним битом, бинарным АКА. Почти так же вероятно, что вы можете получить многобайтовые символы, которые действительно раздражают БД, ожидающую простой текст. Вам лучше декодировать, пока ничего не изменится, затем кодировать один раз, чтобы все нормализовалось, а затем сохранить их.
Жестянщик

1
Я сталкивался с большим количеством HTML с сущностями, которые были закодированы несколько раз, действительно создавая беспорядок. Проверьте люфу ; Его скрубберы были разработаны для этого, если я правильно помню.
Жестянщик

3
Мы настроили нашу базу данных для сохранения Unicode, поэтому я сомневаюсь, что она вообще будет жаловаться. И люфа - это не то, что я ищу, я не хочу избавляться от тегов html - во всяком случае, сейчас.
Костас

1
это 2015, unescapeHTML по-прежнему опускает некоторые из сущностей, таких как A
sharp

47

Я думаю, что камень Nokogiri также хороший выбор. Он очень стабилен и имеет огромное содействующее сообщество.

Образцы:

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

или

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, да, я думаю, что это зависит от спроса. Как видно из обсуждений в этой теме, CGI.escapeHTMLвозможно, не удалось решить некоторые случаи. С другой стороны, если вам нужен полный набор поддержки, я уверен, что Nokogiriэто хороший выбор.
Хоанг Ле

6
Кроме того, если вы уже используете Nokogiri для анализа HTML-кода, нецелесообразно устанавливать еще один гем для этой цели. Например, я использую гем Sanitize для очистки HTML. Оказывается, этот драгоценный камень использует Нокогири под капотом, и поэтому было бы стыдно не воспользоваться этим. Спасибо @HoangLe за совет!
Томалла

1
Примечание: CGI::escapeHTMLне избегает немецких символов, таких как äöüß, а может и больше ... С Nokogiri я еще не проверял, но это было бы плюсом.
Красота

HTMLEntities будет легким и способным выбором. Я часто использую Nokogiri, и, если я не загрузил его, я бы использовал HTMLEntities. CGI устарела.
Оловянный Человек

36

Для декодирования символов в Rails используйте:

<%= raw '<html>' %>

Так,

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

будет выводить

<br>

5
Это работает только в представлении, хотя. Мне нужно то, что работает в ActiveRecord тоже.
Костас

3
Только что протестировано в отладчике - raw '& lt br & gt' ==> '& lt br & gt'.
Уилл Томлинс

13
#rawничего не декодирует Это говорит представлению не кодировать строку. Это делается путем переноса строки в a ActiveSupport::SafeBuffer, которая в свою очередь имеет флаг ( html_safe?), установленный в значение true. Представление использует этот флаг, чтобы определить, что строка может быть вставлена ​​непосредственно в HTML без экранирования. Мне нравится воспринимать программиста html_safeкак указание на то, что рассматриваемая строка уже правильно экранирована.
Моксли Страттон

9

Если вы не хотите добавлять новую зависимость только для того, чтобы сделать это (например HTMLEntities), и вы уже используете ее Hpricot, она может как выйти, так и удалиться. Он обрабатывает гораздо больше, чем CGI:

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

5
Примечание для тех, кто смотрит на это сейчас - Hpricot больше не поддерживается.
SamStephens

2
Используйте Nokogiri , который является стандартом по умолчанию для анализа XML / HTML, вместо Hpricot.
Жестянщик

0

Вы можете использовать htmlasciiдрагоценный камень:

Htmlascii.convert string

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

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

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

Я думаю, что добавляя html_safe к любому введенному пользователем тексту, вы говорите, что это безопасно, когда возможно, что это небезопасно. Это подвергнет ваших пользователей риску, когда они загрузят это представление.
user1515295

Я не знаю, почему так негативно. Я перепробовал все решения в этом вопросе. Только это отлично работает. Что касается безопасного HTML, пользователь ХОЧЕТ отобразить HTML, тогда HTML_SAFE будет правильным.
Диего
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.