如何在Ruby中编码/解码HTML实体?


200

我正在尝试解码一些HTML实体,例如'&amp;lt;'变成'<'

我有一个古老的宝石(html_helpers),但它似乎已经被抛弃了两次。

有什么建议吗?我将需要在模型中使用它。


6
刚刚找到的“ htmlentities”(htmlentities.rubyforge.org
Kostas,

我应该指定我从许多不同的站点获取html,并将其另存为纯文本格式保存在数据库中
Kostas,2009年

1
虽然使用CGI的投票最多,但不要。这就像获取所有Active Support以获得单一方法一样。而是使用HTMLEntities,如所选答案中所述。
锡人

Answers:


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

Zdrasti Ivailo。谢谢你的评论; 它解决了我如何在Ruby中呈现XML字符实体引用的问题?以及!
乔什·格洛弗

4
是啊,在HTMLEntities宝石案件如涉及&aring;&mdash;CGI.unescapeHTML没有。
thomax 2014年

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二进制。几乎有可能,您最终都会得到多字节字符,这实际上会激怒期望纯文本的数据库。您最好先进行解码,直到没有任何变化为止,然后再编码一次,以便对所有内容进行标准化,然后再存储它们。
Tin Man 2010年

1
我遇到了很多HTML,这些HTML的实体已被多次编码,确实使事情变得一团糟。签出丝瓜络;如果我没记错的话,它的洗涤器就是为此而设计的。
Tin Man 2010年

3
我们已经将数据库设置为保存Unicode,所以我怀疑它会抱怨。丝瓜不是我想要的东西,我不想摆脱html标签-无论如何现在都不是。
Kostas,

1
在2015年,unescapeHTML仍然省略了一些实体,例如A急性
nurettin 2015年

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是一个不错的选择。
昂勒2015年

6
另外,如果您已经在使用Nokogiri进行一些HTML解析,则仅出于此目的而安装另一个gem是不合理的。例如,我正在使用Sanitize gem清理HTML。事实证明,这颗宝石是在引擎盖下使用Nokogiri的,因此不冒险使用它是可耻的。感谢@HoangLe的提示!
Tomalla

1
注意:CGI::escapeHTML不能逃避像äöüß这样的德语字符,也许还有更多……对于Nokogiri,我尚未检查,但这将是一个加分点。
美人

HTMLEntities将是一个轻量级且功能强大的选择。我经常使用Nokogiri,除非我已经加载了Nokogiri,否则我会选择HTMLEntities。CGI已过时。
锡人

36

要在Rails中解码字符,请使用:

<%= raw '<html>' %>

所以,

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

将输出

<br>

5
不过,这仅在视图中有效。我也需要在ActiveRecord中工作的东西。
Kostas,

3
刚刚在调试器中进行了测试-原始'&lt br&gt'==>'&lt br&gt'。
Will Tomlins 2011年

13
#raw不解码任何东西。它告诉视图不对字符串进行编码。它是通过将字符串包装在中来实现的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。
Tin Man


-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是正确的。
迭戈·索玛
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.