2013-03-05 43 views
1

編輯:父類中的preg_match_all元素?

人們似乎認爲我試圖解析HTML,而我是重音我試圖解析日誌幾次,和<option>結構類似到我的日誌。

我的日誌是這個樣子:

!# [2013-03-04 14:51:31] // cluster1 BEGIN \\ 
!## apache: 41 
!## mysql: 31 
!## tomcat: 81 
!## lotus: 985 
!# [2013-03-04 14:51:56] // cluster1 END \\ 
!# [2013-03-04 14:51:56] // cluster2 BEGIN \\ 
!## apache: 13 
!## mysql: 61 
!## tomcat: 6 
!## lotus: 513 
!# [2013-03-04 14:52:13] // cluster2 END \\ 

我不能讓這個正則表達式的工作,也許這是不可能的。需要幫助:)

基本上我想正則表達式來自父母實體的多個子元素。爲了簡潔起見,我將以下拉菜單<select> HTML元素爲例。這實際上將用於日誌解析,但我還不確定它將會是什麼格式,並且下拉元素與我需要的非常接近,而不必解釋日誌的結構。

因此,讓我們假設我們有一個下拉:

<select class="parent"> 
    <option value="1">First child</option> 
    <option value="2">Second child</option> 
    <option value="3">Third child</option> 
    ... 
</select> 

要單獨從父<option>元素,我會使用這樣的:

preg_match_all('/<select class="parent">(.*)<\/select>/is', $source, $matches); 

這是偉大的。但現在我要做的第二preg_match()過濾掉我<option>元素,所以它看起來是這樣的:

preg_match_all('/<option value="(.*?)" >(.*?)<\/option>/is', $matches['1'], $finalMatches); 

而且我得到我的結果就好了。但是有沒有辦法將這兩個命令組合成一個規則?所以它會找到父元素,在這種情況下是<select class="parent">*</select>區塊,並篩選出每個在該父區中找到的<option value="*">*</option>條目?然後我會留下一組完美的父子組合,而不是迭代第一個結果,然後讓每個迭代完成另一個preg_match函數。

+2

如果只有[更簡單的選項](http://stackoverflow.com/questions/3577641/how-to-parse-and-process-html-xml-with-php)。 (如果你足夠熟練,你可以使用正則表達式來匹配複雜的HTML,對於新手來說,它通常不是最好的選擇。) – mario 2013-03-05 12:35:42

+0

在這種情況下,您需要使用'preg_replace_callback' – artnikpro 2013-03-05 12:51:33

回答

2

我認爲這是你在找什麼:

preg_match_all(
    '~(?:<select class="parent">|\G)\s*<option value="(.*?)">(.*?)</option>~i', 
    $source, $matches); 

\G錨匹配到以前的比賽結束位置(或輸入的開始。如果沒有前面的比賽)。所以第一場比賽將包括開始<select>標記和第一個<option>元素,並且每個匹配之後將包含下一個<option>元素 - 它不會跳過在後面的<select>元素中查找匹配。

Here's a demo。我還使用了\K,Match Start Reset運算符,但這不是必需的;我只是認爲它使輸出更易於閱讀。它有效地將所有事情變成一個積極向後看,沒有通常的限制。

+0

謝謝!正是我一直在尋找的 – Matt 2013-03-05 15:26:55