我会这样做:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<p>Whether you want to build a playground, make play a priority in your community, or learn more about Imagination Playground , we've got webinars for you in March!</p>
<p>As always, all our webinars are FREE. All you need to participate is a phone and a computer with an Internet connection.</p>
EOT
doc.encoding = 'UTF-8'
doc.css('p').each do |p|
p.children = p.content.gsub(/Imagination Playground\s/, 'Imagination Playground<i class="fa fa-trademark"></i>')
end
puts doc
结果是:
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body>
# >> <p>Whether you want to build a playground, make play a priority in your community, or learn more about Imagination Playground<i class="fa fa-trademark"></i>, we've got webinars for you in March!</p>
# >> <p>As always, all our webinars are FREE. All you need to participate is a phone and a computer with an Internet connection.</p>
# >> </body></html>
Nokogiri很聪明。当它看到
children=
,它会查看是否接收到字符串。如果是,它将解析该字符串并将其转换为节点,然后用新节点替换现有子节点。这与使用
content=
Nokogiri知道应该是文本,然后将嵌入的标记编码为
<
文件中对此进行了说明。
对于
children=
:
为此节点Node_or_tags设置内部html Node_or_tag可以是Nokogiri::XML::Node、Nokogiri::XML::DocumentFragment或包含标记的字符串。
对于
content=
:
将节点的内容设置为包含字符串的文本节点。字符串得到XML转义,而不是解释为标记。
如果我想保留段落中的html标记,那么这将不起作用,请尝试这样做
<p>fsome test and then <b>bold</b></p>
您正在更改要求。不要那样做。明确您的需求,这样我们就可以回答一次真正的问题。
需要一个小的修改来获取所需标签的内容。使用
children.to_html
获取嵌入节点的HTML字符串
gsub
并使用其结果:
require 'nokogiri'
doc = Nokogiri::HTML('<p>Imagination Playground<b>foo</b></p>')
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>Imagination Playground<b>foo</b></p></body></html>
修改DOM:
doc.search('p').each do |p|
p.children = p.children.to_html.gsub(/Imagination Playground\s?/, 'Imagination Playground<i class="fa fa-trademark"></i>')
end
puts doc
现在看起来像:
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html><body><p>Imagination Playground<i class="fa fa-trademark"></i><b>foo</b></p></body></html>
注意我正在使用
search
而不是
css
。使用泛型方法,而不是更具体的方法。如果需要,它可以更容易地切换到XPaths。
此外,我在
全球供应链
有条件地获取单个尾随空格(如果可用)。用HTML做这一点并不重要,因为浏览器会吞掉空白,但如果您处理的是常规文本文档或预格式化文本,那么这是正确的方法。
关于Nokogiri所看到的更多细节:
doc.search('p').first
# => #(Element:0x3fd222462204 {
# name = "p",
# children = [
# #(Text "Imagination Playground"),
# #(Element:0x3fd2224608f0 { name = "b", children = [ #(Text "foo")] })]
# })
doc.search('p').first.children
# => [#<Nokogiri::XML::Text:0x3fd222461688 "Imagination Playground">, #<Nokogiri::XML::Element:0x3fd2224608f0 name="b" children=[#<Nokogiri::XML::Text:0x3fd22245fe64 "foo">]>]