2011-07-17 57 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]