2015-12-27 28 views
2

我有一个简单的HTML文档:从图像中创建的HTML链接使用Ruby

<div should-not-be-replaced=":smile:"> 
    Hello :smile:! 
</div> 

我怎么会跟<img src="smile.png">更换:smile:文本,但保持第一: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 
+0

不要为此使用'遍历'。使用选择器和Nokogiri中的许多方法之一来定位特定节点。 –

回答

1

我的解决方法是非常相似的苦的,虽然我已经试过用一个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 
完全替换内容的文本处理的情况下被替换的文字可能是在源文本中多次
+0

谢谢!请查看我对关于“add_next_sibling”问题的回答的评论,在文本的末尾添加图像标签,而不是将其替换为正确的位置。 – sina

+1

在这种情况下使用'add_next_sibling'不会影响替换文本的位置,因为我使用原始正则表达式来完全替换整个内容文本。 – maniacalrobot

+0

我明白了,太棒了!谢谢! – sina

-1

您的意思是返回&lt&gt

我建议换CGI#unescape_html方法

尝试,

require 'cgi' 
CGI::unescape_html(doc.to_s) 
+0

Nokogiri本身可以管理这个,而不需要使用CGI。我建议研究如何。 –

1

我认为这可能是你想要什么,并且它还涉及两个冒号之间等字符串:东西:和生产“的东西。 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 
+0

谢谢!问题是新的''标签总是被添加到文本的末尾。所以这两个字符串'你好:微笑:'和':微笑:你好'将被替换为'你好' – sina

+0

你是对的,我想念这种情况,对不起。 –

0

由于它迫使Nokogiri遍历文档中的每个节点,所以您正在使它变得非常困难,并且使用了traverse,在一个昂贵的大页面中。

而是利用选择器来查找特定的节点(S)你想:

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,该发现首次出现。如果您需要处理多个请使用searchsearch返回一个NodeSet,它就像一个数组,所以你需要遍历它。这是Stack Overflow和其他地方的无数例子。

+0

谢谢!添加属性值中的':smile:'作为示例来说明属性值应该保持不变。 – sina