Як кодувати / декодувати HTML-сутності в Ruby?


200

Я намагаюся розшифрувати деякі HTML-об'єкти, наприклад, '&amp;lt;'стати '<'.

У мене є старий дорогоцінний камінь ( html_helpers ), але він, здається, був кинутий двічі.

Будь-які рекомендації? Мені потрібно буде використовувати його в моделі.


6
Щойно знайдено "htmlentities" ( htmlentities.rubyforge.org )
Костас

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

1
Хоча більшість голосів припадає на використання CGI, не варто. Це як втягнути всю Активну підтримку, щоб отримати єдиний метод. Натомість використовуйте HTMLEntities, як зазначено у вибраній відповіді.
Олов'яний чоловік

Відповіді:


153

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не робить.
томакс

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-об'єкти для зберігання як звичайний текст у базі даних, тоді очікуйте, що ваша база даних скажеться на погані символи. Зашифровані сутності закодовані, щоб вони могли передати як звичайний текст. Розшифровка їх може, і швидше за все, поверне їх до символів верхнього біта, AKA, бінарних. Майже так само, ймовірно, ви можете отримати багатобайтові символи, які дійсно будуть дратувати БД, що очікує простого тексту. Вам краще розшифрувати, поки нічого не зміниться, потім кодуйте один раз, щоб все нормалізувалося, а потім зберігайте їх.
Олов'яний чоловік

1
Я стикався з великою кількістю HTML із сутностями, які були кодовані кілька разів, справді роблячи безлад. Перевірте коровай ; Його скребки були призначені для цього, якщо я правильно пам’ятаю.
Олов'яний чоловік

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

1
настав 2015 рік, unescapeHTML все ще опускає деякі суб'єкти, такі як «Гострий»
Нуреттін

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. Виявляється, цей дорогоцінний камінь використовує Nokogiri під кришкою, і тому було б соромно не брати на себе переваги. Дякую @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програмістом вказівку на те, що відповідний рядок уже належним чином вийшов.
Moxley Stratton

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 у будь-який текст, що вводиться користувачем, ви говорите думці, що це безпечно, коли можливо, що це не безпечно. Це загрожує вашим користувачам під час завантаження цього перегляду.
користувач1515295

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