2014-08-28 52 views
1

我正在嘗試編寫匹配字符串後跟可選模式的正則表達式。匹配文本後跟可選模式

這裏就是我想匹配match/string

/any/path/match/string 
/any/path/match/string/pattern 
/any/path/match/string/pattern/something/else 

/any/path/pattern是靜態的文字和match/string可以是任何文字的三個輸入字符串的例子。

我已經試過這

print $1 if m,/any/path/(.+)(?=/pattern/)?, 

,但它在整個輸入字符串,因爲.+是貪婪匹配。

+0

語法像'(?= ...)'是一個空操作。那麼......「*之後是一個可選模式*」,沒有什麼意義。你想做什麼?請給出具體的例子。 – 2014-08-28 23:14:06

+0

基本上我試圖匹配「/任何/路徑」和「/ pattern」之間的文本,其中「/ pattern」可能存在或不存在於輸入字符串中。 – quicoju 2014-08-28 23:17:27

+0

問題是,因爲'match/string'可能是*「任何文本」*,所以它可能是'/ match/string/pattern/something/else'。如果你正確地定義你想要做的事情,那麼代碼將更加明顯 – Borodin 2014-08-29 01:42:42

回答

1

正如你已經猜到,你的問題是貪婪匹配。

記住,如果你有一個正則表達式的麻煩,你總是可以打破邏輯到步驟:

print +(split m{/pattern\b}, $1)[0] if m{^/any/path/(.+)}; 

爲此使用單一的正則表達式,雖然做的,有兩種做法:

  1. 限制任何字符.可以通過在其之前放置負面預測聲明來匹配。
  2. 使用與結束邊界聯合的非貪婪匹配。

下面演示了這兩種方法:

use strict; 
use warnings; 

while (<DATA>) { 
    print "\nString = $_"; 

    if (m{^/any/path/((?:(?!/pattern\b).)*)}x) { 
     print " Neg Lookahead  - $1\n" 
    } 

    if (m{^/any/path/(.*?)(?:/pattern\b|$)}x) { 
     print " Nongreedy with bound - $1\n" 
    } 
} 
__DATA__ 
/any/path/match/string 
/any/path/match/string/pattern 
/any/path/match/string/pattern/something/else 

輸出:

String = /any/path/match/string 
    Neg Lookahead  - match/string 
    Nongreedy with bound - match/string 

String = /any/path/match/string/pattern 
    Neg Lookahead  - match/string 
    Nongreedy with bound - match/string 

String = /any/path/match/string/pattern/something/else 
    Neg Lookahead  - match/string 
    Nongreedy with bound - match/string 
+1

'print +(split m {/ pattern \ b},$ 1)[0] if m {^/any/path /(.+)} '?我不知道那是幹嘛的! – Borodin 2014-08-29 01:46:02

0

你可以使用這個表達式:

/any/path/(\w+?/\w+)/pattern|/any/path/(\w+?/\w+)$ 

Working demo

enter image description here