我有一个简单的HTML文档:
<div should-not-be-replaced=":smile:">
Hello :smile:!
</div>如何将:smile:文本替换为<img src="smile.png">,但保持第一个:smile:不变,以获得以下结果:
<div should-not-be-replaced=":smile:">
Hello <img src="smile.png">!
</div>我尝试过这样做,但是Nokogiri将我的HTML转义为纯文本:
doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.traverse do |x|
next unless x.text?
x.content = x.text.gsub(':smile:', '<img src="smile.png">')
end发布于 2015-12-27 11:36:38
我的解决方案非常类似于Ku的解决方案,尽管我尝试通过使用HTML片段完全替换内容文本来处理被替换文本可能多次出现在源文本中的情况
doc = Nokogiri::HTML::DocumentFragment.parse(DATA.read)
doc.traverse do |x|
next unless x.text?
if x.text.match(%r{:(\w+):})
replace_text = x.text.gsub(%r{:(\w+):}, "<img src='#{$1}.png'>")
x.content = ""
x.add_next_sibling replace_text
end
end发布于 2015-12-27 11:11:45
我认为这可能是您想要的,而且它还处理两个冒号之间的字符串,比如: think :并生成"something.png“。
doc = Nokogiri::HTML::DocumentFragment.parse(html)
doc.traverse do |x|
if x.text? && x.content =~ /:\w+:/
x.content = x.content.sub(/:(\w+):/, '')
a = Nokogiri::HTML::DocumentFragment.parse('<a src="'+$1+'.png">')
x.add_next_sibling(a)
end
end发布于 2015-12-28 17:54:12
这样做太难了,而且使用traverse太慢了,因为它迫使Nokogiri遍历文档中的每个节点;在一个代价很高的大页面中。
相反,利用选择器来查找所需的特定节点:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<div parm=":smile:">
Hello :smile:!
</div>
EOT
div = doc.at('div[parm=":smile:"]')
div.inner_html = div.text.sub(/:smile:/, '<img src="smile.png">')
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>
<div parm=":smile:">
Hello <img src="smile.png">!
</div>
</body></html>我使用的是at,它可以找到第一次出现。如果您需要处理多个进程,那么使用search。search返回一个NodeSet,它类似于一个数组,因此您需要对它进行迭代。这是在堆栈溢出和其他地方这样做的无数例子。
https://stackoverflow.com/questions/34479548
复制相似问题