2010-06-01 90 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