2014-01-12 29 views
0

我想在行結束(不嵌套)之前匹配具有不平衡令牌的行。Perl正則表達式匹配行結束前的不平衡令牌

如果令牌是單個字符並且/{[^}]*$/,則很容易匹配行。它匹配開放{線,如:

Some text {some text 

不要在同一行狀匹配終止對:

Some text {some} text 

這就是它應該如何工作。但我正在努力匹配不平衡的多字符標記,如<a> </a>或任何<blah> </blah>

基本上需要類似於上面單個字符匹配正則表達式替換[^}]*以否定多行字符串在行尾錨點之前的否定。 帶有負向前視或向後看像|<a>.*(?!</a>).*$|的實驗並不富有成效(當然,因爲如果(?!..)沒有嚴格地錨定,那麼它總會找到一個地方,這個斷言是真實的,即閉合標記不存在,因此它匹配任何具有一個開放的標籤..

直觀感覺好像失去了一些東西簡單(或不)

+0

正則表達式對平衡令牌不好,因爲它們不能計數。 – Barmar

+0

@Barmar:除了我們在這裏討論Perl,它支持遞歸正則表達式和子例程。 – nhahtdh

+0

@Barmar是的,我同意,但我試圖實現更簡單的事情,因爲沒有嵌套,所以它足以在行結束前匹配打開的標記。基本上匹配除結束標記之外的任何字符都非常簡單,但如何匹配任何內容除了打開的令牌和行結束錨之間的子字符串(閉合標記)? –

回答

3

你可以做'<a>(?!.*</a>)'

負前瞻(?!.*</a>)斷言,這是不可能找到</a>領先的字符串中。引擎基本上耗盡了所有可能性,然後才斷定在字符串中找不到前面的模式。

+0

+1更好的解決方案 – nhahtdh

+0

是的,它確實有效。我怎麼能錯過它:)不是說完全理解它爲什麼起作用......但是謝謝! –

+0

我記得嘗試過這種模式,但停留在行尾,並沒有奏效:'(?!。*)$'(不匹配任何行)。但沒有錨定它工作正常。所以出現了一個錯誤...... –

1

您需要檢查</a>是不是有你處理每一個字符:

|<a>(?:(?!</a>).)*$| 

你是正確約

|<a>.*(?!</a>).*$| [...](自然,因爲它似乎如果(?!..)沒有嚴格固定那麼它總是會找到一個地方,這種說法是真實的

第一.*讓引擎找到有些地方</a>之後不能匹配,甚至可以在<a>text</a>的最後>。 (實際上,對於這個正則表達式,引擎會一直匹配到最後,因爲無論如何你都不能匹配字符串末尾的</a>)。

+0

謝謝,我不得不說,前瞻斷言的邏輯是不容易的。 –