2014-09-25 39 views
1

我正在使用nokogiri来读取文件的内容并执行一些替换操作。最后,我使用doc.to_s将内容作为字符串取回。Nokogiri在读取html字符串时编码方括号

我简化了代码如下

html_string = '<a href="[foo]">foo</a>' 
doc = Nokogiri::HTML(html_string) 
doc.to_s 

我得到的输出是

<a href=\"%5Bfoo%5D\">foo</a> 

我想是离开的方括号机智。请注意,当方括号不是HTML标记的属性时,它们不会被编码。

有关如何解决此问题的任何想法?

+1

技术上方括号不应该在这样一个URL,因此引入nokogiri只是秉承标准。这组允许的字符实际上很小。 – tadman 2014-09-25 20:28:17

回答

2

我不认为有一种方法可以防止Nokogiri这样做,因为Nokogiri旨在生成正确的HTML输出。我能想到的最佳解决方案是后处理来自Nokogiri的输出:

doc_str = '<a href="%5Bfoo%5D">foo</a>' 
doc_str.gsub!(/%5B(.+?)%5D/i, '[\1]') 
# => <a href="[foo]">foo</a> 

我希望这很有帮助。

+1

如果您不小心,可能会导致各种问题,所以不要过于宽泛地适用。 – tadman 2014-09-25 20:27:33

+1

它当然可以。小心。 (这是大多数模板引擎使用像'{{this}}'这样的占位符的原因,因为这种方式比单个方括号更不太可能出现在屏幕上。) – 2014-09-25 21:42:55

0

或者你可以做得更简单。

CGI.unescape(doc.to_s) 
+0

当然,如果您不希望URL转义字符出现文档中的任何位置。当我们只关注总是出现在一起的两个角色时,似乎过度杀伤。 – 2014-09-25 21:45:30

+1

如果仅将它应用于'href's,这可能是一个很好的答案 – 2014-09-26 02:23:26

0

我一直工作在一个simliar问题,虽然没有方括号,有效在HREF中有在使用它们的情况。在我的情况下,我需要保持它们与客户的系统兼容。

2个有用的事实:

1 - 引入nokogiri校正HREF时,将其转换为文本文档。如果你加载一个html片段并查看href,你会发现方括号在那里。

2-删除方括号只发生在href属性中,它们在其他属性中被允许。例如data-raw-href

所以,如果你加载一个文件,然后复制href属性,你可以保留原来的。您仍然需要对最终文本进行后期处理,以将data-raw-href转换回href。

一个例子(你可以在IRB试试)

require 'nokogiri' 
doctext = '<html><body><a href="[my dodgy href]">link text</a></body></html>' 
doc = Nokogiri.HTML(doctext) 
a_tag = doc.css('a')[0] 
a_tag['data-raw-href'] = a_tag['href'] 
doc.to_s 

产量:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
<html><body> 
<a href="%5Bmy%20dodgy%20href%5D" data-raw-href="[my dodgy href]">link text</a> 
</body></html>