2010-06-01 88 views
1

我想弄清楚为什么当“单线”选项打开时,带有负向预览的正则表达式失败。C#正则表达式:负向预测失败,单线选项

实施例(简化):

<source>Test 1</source> 
<source>Test 2</source> 
<target>Result 2</target> 
<source>Test 3</source> 

此:如果单个行选项是

<source>(?!.*<source>)(.*?)</source>(?!\s*<target) 

将失败,并且如果该单线选项是关闭将起作用。例如,这可以工作(禁用单行选项):

(?-s:<source>(?!.*<source>)(.*?)</source>(?!\s*<target)) 

我的理解是单线模式只允许点“。”。以匹配新的行,我不明白为什么它会影响上面的表达。

任何人都可以解释我在这里失踪?

::::::::::::::::::::::

编辑:(?!。*)是提前负外观没有捕获组。

<source>(?!.*?<source>)(.*?)</source>(?!\s*<target) 

如果单线模式打开也会失败,所以它看起来不像是贪婪问题。尝试在一个正则表达式的设计师(如快报或拉德正则表达式):

使用单线OFF,它匹配(如预期):

<source>Test 1</source>  
<source>Test 3</source> 

使用单线ON:

<source>Test 3</source> 

我不明白为什么它与第一个不匹配:它不包含第一个负面观察,所以它应该匹配表达式。

+1

通过解析这个使用html解析器而不是正则表达式来帮助你自己一个忙吧http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – Amarghosh 2010-06-01 08:18:12

+0

等待来自John Saunders的评论:3 ... 2 ... 1 ... – 2010-06-01 08:33:23

+0

@Amarghosh。在我的情况下不相关。是的,有一些使用正则表达式是需要做的事情。 – Sylverdrag 2010-06-01 09:42:42

回答

2

我相信这是你在找什么:

<source>((?:(?!</?source>).)*)</source>(?!\s*<target) 

的想法是,你每次打开一个字符一个匹配,但只有在确信它不是</source>第一个字符。另外,如果将/?添加到预览中,则不必使用非贪婪量词。

+0

+1;我在我的建议“修复”中的一个错误(现在删除),这一个工程 – polygenelubricants 2010-06-01 12:58:10

+0

非常好。很多,艾伦! – Sylverdrag 2010-06-01 14:59:30

2

它“失败”的原因是因为你似乎放错了负向预测。

<source>(?!.*<source>)(.*?)</source>(?!\s*<target) 
     ^^^^^^^^^^^^^^ 

现在,让我们考虑一下(?!.*<source>)在这里所做的:它是一个先行,指出有NO匹配.*<source>从该位置。

那么,在单线模式下,.匹配所有内容。在匹配前两个<source>后,出现IS其实.*<source>!所以前两个<source>的负向预测失败。

在最后的<source>,.*<source>不再匹配,所以负向预测成功。模式的其余部分也会成功,这就是为什么您只能以单行模式获得<source>Test 3</source>的原因。

+1

使用负面字符类更加简单快捷:'([!<]*)(?!\ s * )' – 2010-06-01 10:12:46

+1

啊!现在我明白了!谢谢! – Sylverdrag 2010-06-01 14:55:16

+0

@pent:在这种情况下我不能使用字符类,因为源标签可以包含其他标签(和方括号),这些标签也需要匹配 – Sylverdrag 2010-06-01 14:56:20