【发布时间】:2012-07-20 04:03:23
【问题描述】:
我想这很常见,以至于它是一个已解决的问题,但作为丝瓜和 Nokogiri 的新手,我还没有找到解决方案。
我正在使用 Loofah,一个包装 Nokogiri 的 HTML 清理器库,用于清理一些 HTML 文本以供显示。但是,该文本有时会出现在电子邮件地址等< 和> 字符之间,例如< foo@domain.com >。 Loofah 将其视为 HTML 或 XML 标记,并将其从文本中剥离。
有没有办法防止这种情况发生,同时还能很好地清除实际标签?
编辑:这是一个失败的测试用例:
require 'test/unit'
require 'test/unit/ui/console/testrunner'
require 'nokogiri'
MAGICAL_REGEXP = /<([^(?:\/|!\-\-)].*)>/
def filter_html(content)
# Current approach in a gist: We capture content enclosed in angle brackets.
# Then, we check if the excerpt right after the opening bracket is a valid HTML
# tag. If it's not, we substitute the matched content (which is the captured
# content enclosed in angle brackets) for the captured content enclosed in
# the HTML entities for the angle brackets. This does not work with nested
# HTML tags, since regular expressions are not meant for this.
content.to_s.gsub(MAGICAL_REGEXP) do |excerpt|
capture = $1
Nokogiri::HTML::ElementDescription[capture.split(/[<> ]/).first] ? excerpt : "<#{capture}>"
end
end
class HTMLTest < Test::Unit::TestCase
def setup
@raw_html = <<-EOS
<html>
<foo@bar.baz>
<p><foo@<b class="highlight">bar</b>.baz></p>
<p>
<foo@<b class="highlight">bar</b>.baz>
</p>
< don't erase this >
</html>
EOS
@filtered_html = <<-EOS
<html>
<foo@bar.baz>
<p><foo@<b class="highlight">bar</b>.baz></p>
<p>
<foo@<b class="highlight">bar</b>.baz>
</p>
< don't erase this >
</html>
EOS
end
def test_filter_html
assert_equal(@filtered_html, filter_html(@raw_html))
end
end
# Can you make this test pass?
Test::Unit::UI::Console::TestRunner.run(HTMLTest)
我们目前正在使用一些非常邪恶的正则表达式黑客来尝试实现这一点,但正如上面的评论所述,它不适用于“嵌套”在非标签中的标签。我们实际上也想保留<b class="highlight"> 元素。
下面的示例没有使用丝瓜络,但应用程序本身在其他地方使用丝瓜络,所以在这里添加它并不难。我们只是不确定应该使用哪些配置选项(如果有的话)。
【问题讨论】:
-
文本是否实际包含“
-
如果您提供一个显示问题的最小脚本(连同它的输入和输出),这将更容易回答。
-
@mark-thomas :我已编辑问题以添加失败的测试用例。我希望它可以解决这个问题。
-
@andy-waite :正如上面的测试所示,文本实际上包含一个