我有一个相当长的文本,其中包含HTML标记内的一些字符串(主要是h1
和h2
)。我需要完全删除它们,这意味着我需要一种方法来查找包含在某些HTML标记中的文本,然后将它们从原始文本中删除。
我尝试使用gsub
,但无法弄清楚如何构建正则表达式或有意义的东西。
答案 0 :(得分:1)
查找和删除节点很简单:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<h1>foo</h1>
<h2>bar</h2>
<p>This is some text</p>
</body>
</html>
EOT
doc.search('h1, h2').remove
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >>
# >>
# >> <p>This is some text</p>
# >> </body></html>
我正在使用search
一个CSS选择器h1, h2
,它将找到所有<h1>
和<h2>
个节点,并将它们作为NodeSet返回。 NodeSet就像一个数组; remove
只是遍历NodeSet并删除其所有元素。
如果要查看文本中的节点,请稍微扩展代码:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<h1>foo</h1>
<h2>bar</h2>
<h1>baz</h1>
<p>This is some text</p>
</body>
</html>
EOT
doc.search('h1, h2').select{ |n| n.text[/\b(?:foo|bar)\b/] }.map(&:remove)
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >>
# >>
# >> <h1>baz</h1>
# >> <p>This is some text</p>
# >> </body></html>
text
返回节点的文本内容。 /\b(?:foo|bar)\b/
在该文字中查找"foo"
或"bar"
字样。这导致了一个Array,所以我不能使用NodeSet的remove
方法。相反,我可以将它传递给map
,它将迭代select
返回的每个节点,并将Nokogiri :: Node.select发送给它。它有点复杂,但到了那里。
XPath选择器可以查看节点的文本内部以替换部分Ruby代码,但它们非常难看。我更喜欢保持简单。
答案 1 :(得分:0)
您无法使用regex
来解析HTML
(请参阅&#34; RegEx match open tags except XHTML self-contained tags&#34;)。您可能希望查看像Nokogiri这样的HTML解析gem:
require 'nokogiri'
doc = Nokogiri::HTML(my_html)
h1s = doc.css('h1').map(&:text)
h2s = doc.css('h2').map(&:text)