2011-05-23 80 views
2

這裏是(從原來的簡化)示例文本:負回顧後發問題

<start1> 
<name="4654"> 
bla bla bla bla 
<tags="bla" model="c"> 
bla bla bla bla 
<start2> 
<name="12346"> 
bla bla bla bla 
<tags="bla" model="d"> 
bla bla bla bla 
<start3> 
<name="73535"> 
bla bla bla bla 
<tags="bla" model="c"> 
<start4> 
<name="546875"> 
bla bla bla bla 
<tags="bla" model="c"> 
bla bla bla bla 

這裏是我的正則表達式(點相匹配的新行選項上)

name="([\d]+)".+?(?<!start)tags="([^"]+?)" model="c" 

正如你可以看到有4塊,但我需要匹配那些與模型=「C」。但是.+?正在捕獲超過它的需求。屏蔽負面lookbehind壓制它沒有工作......任何想法如何排除塊?

更新(澄清我想達到的目標):

出的樣本數據我想匹配以下3塊:

首場比賽

<name="4654"> 
bla bla bla bla 
<tags="bla" model="c"> 

第二場比賽

<name="73535"> 
bla bla bla bla 
<tags="bla" model="c"> 

第三場比賽

<name="546875"> 
bla bla bla bla 
<tags="bla" model="c"> 
+0

如果是XML,最好使用XPath。 – 2011-05-23 00:05:20

+5

這看起來不像XML。這是更糟的事情。 :) – Amadan 2011-05-23 00:08:35

+0

它不是。我剛剛使用了XML元素來簡化示例數據。 – Pablo 2011-05-23 00:08:50

回答

2

是否總是在( startnametags)這種格式,( startnametags),等等?如果是這樣,你甚至可以沒有查找。

/<name="(\d+)"[^<]+?<tags="([^"]+?)" model="c">/s 

這工作,因爲你知道你遇到的將是緊隨tags標籤下一<。我們可以保證是這種情況,還是我們需要更一般地允許混合中的其他標籤?

此外,您是否需要在<tags>之後和下一個<start>之前捕獲文本?如果是這樣,你可以在最後加上一點額外的東西。

/<name="(\d+)"[^<]+?<tags="([^"]+?)" model="c">[^<]*(?!<start)/s 

好了,根據您的意見,這是情況並非如此。然後,抓住那個。


更新

好了,怎麼回合這個呢?

/<name="(\d+)"(?:(?!<start).)+<tags="([^"]+?)" model="c">/s 

這實際上使用了一個向前看,而不是向後看。一個簡單的前瞻/後向只會聲明一個字符串出現在一段文本之前或之後,而不是在之前。通過檢查每個字符與((?!str).)+,你有效地確保「str」不包含整個的文字。

它可能看起來很奇怪,我使用一個超前檢查<start,而對於start一個回顧後會是什麼樣子(?<!start)而不是(?!<start)
認爲(?!(<start))(?<!(start))對比。

我加了(?:),所以它不會捕獲。

+0

@Wiseguy:名稱和標籤之間的文本可能包含'<' or '>',應基於「開始」關鍵字是否存在。不,我不需要捕獲「」和「」的網絡。 – Pablo 2011-05-23 02:06:44

+0

@Michael查看更新。檢查「<開始」以防單詞「開始」也可能出現。 – Wiseguy 2011-05-23 02:13:39

+0

@Wiseguy:做了一個小把戲,現在如果你能稍微詳細一點,我會雙倍感謝:) – Pablo 2011-05-23 02:24:52

0

而不是一個負面lookbehind,嘗試更改您的排除模式,使模型=「C」非貪婪。

name="([\d]+)".+?(?!model=)tags="([^"]+?)" model="c" 
+0

它仍然合併塊''和'' – Pablo 2011-05-23 02:08:26