2011-05-23 56 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