2011-07-17 91 views
1

例如:到标签后得到的文本,包含另一个文本

<p> 
<b>Member Since:</b> Aug. 07, 2010<br><b>Time Played:</b> <span class="text_tooltip" title="Actual Time: 15.09:37:06">16 days</span><br><b>Last Game:</b> 
<span class="text_tooltip" title="07/16/2011 23:41">1 minute ago</span> 
<br><b>Wins:</b> 1,017<br><b>Losses/Quits:</b> 883/247<br><b>Frags/Deaths:</b> 26,955/42,553<br><b>Hits/Shots:</b> 690,695/4,229,566<br><b>Accuracy:</b> 16%<br> 
</p> 

我想1,017。它是标签后面的文本,其中包含文本Wins:
如果我使用正则表达式,它将是[/<b>Wins:<\/b> ([^<]+)/,1],但如何与Nokogiri和XPath做到这一点? 或者我应该更好地解析正则表达式的这一部分页面?

+0

当任务非常简单时,和/或当您控制HTML或XML的生成时,正则表达式很好。当这代人离开你的控制时,它变得更加冒险,因为文件可能会意外改变,导致更复杂的正则表达式和/或支持代码。解析器往往会避免这种情况的发生,从而使得长期支持变得更容易。根据我自己的经验,不得不清理和维护其他人的代码,通过切换到一个好的分析器,同时简化它,这在生产环境中非常合适,我能够大幅度减少基于正则表达式的代码。 –

+0

虽然可以编写复杂的正则表达式来处理更多情况,但它也变成了一项开发和维护任务,导致了熵设置。重要的是要记住,尽管可以使用特定工具完成某些工作,使用另一个可能会更好。正则表达式常常是这种情况;这是性感和男子气概使用,但这些不是很好的理由选择它。相反,使用正则表达式当它显然是更短,更简单的路径以达到期望的结果时,则需要长期支持。 –

+0

@锡匠,下次我写一个关于解析的问题时,我会补充* pleeease不要开始holywar,所以它充满了它,我们不需要更多的空论辩论的副本,以防止它在答案中出现。但无论如何感谢您的想法。 – Nakilon

回答

3

这里

doc = Nokogiri::HTML(html) 
puts doc.at('b[text()="Wins:"]').next.text 
+0

添加尾随'。文字“到你的”下一个“,这将是我的建议答案。 –

+0

你的愿望是我的命令,完成! – akuhn

1

您可以使用此XPath://*[*/text() = 'Wins:']/text()它将返回1,017

关于正则表达式:RegEx match open tags except XHTML self-contained tags

+0

你对正则表达式不正确。提及正则表达式不适合XML过时。阅读关于递归正则表达式的更多信息。 – Nakilon

+0

@Nakilon,“XML过时了”是什么? –

+0

“正则表达式不适合XML”已过时。 – Nakilon

1

我会用纯的XPath,如:

"//b[.='Wins:']/following::node()[1]" 

我听说过遍万(和大师)“从不使用正则表达式来解析XML“。你能提供一些“令人震惊的”参考证明这句话不再有效吗?

+0

我听说过千次(和来自大师)*“如果正则表达式足够,并且是最简单的解决方案,就使用它们”*。你能提供一些“令人震惊”的参考证明我不能在例如我的当前任务中使用正则表达式吗? – Nakilon

+1

这是一个普遍的建议,在你的具体情况下,你是真实的,你可以继续使用正则表达式,而不用担心太多。不过,我认为当您有更复杂的节点选择时,XPath变得不可或缺。 –

+1

其他考虑:如果你正在考虑使用Nokogiri来完成这个小任务,那么你应该使用regex。如果您已经在您的应用程序中使用Nokogiri,或者如果您的选择复杂化,您应该充分利用XPath和CSS选择器。 –

0

使用

//*[. = 'Wins:']/following-sibling::node()[1] 

在情况下,这是不明确的(选择多于一个的节点)时,可以指定更严格的表达式:

//*[. = 'Wins:']/following-sibling::node()[self::text()][1] 

或者:

(//*[. = 'Wins:'])[1]/following-sibling::node()[1] 

或者:

(//*[. = 'Wins:'])[1]/following-sibling::node()[self::text()][1] 
相关问题