2012-08-07 51 views
0

我在我的應用程序中有一個類似facebook的提及功能。用於匹配所有的PHP正則表達式

創建帖子或評論時,用戶可以使用@ sign來提及其他用戶。 我使用以下jQuery插件:http://podio.github.com/jquery-mentions-input/

提到以下面的格式生成: @@ [馬爾科Kurjonen:2] 所以「@@ [使用名稱:USER_ID]

目前我具有以下圖案(和代碼):

$pattern = "/@@\[(.*):(\d*)] /ims"; 

$matches = array(); 
preg_match_all($pattern, $input, $matches); 
Zend_Debug::dump($matches); 
$output = preg_replace($pattern, "<a href=\"". $this->view->baseUrl("user") ."/$2\" class=\"tooltip\">$1</a>", $input); 

問題是,它不僅會第一次提到

例字符串:

$input = "Hello @@[Markku Pelkonen:7] and @@[Marko Kurjonen:2]" 

只有第一個用戶通過preg_replace進行轉換。

BR,馬爾科

回答

2

你可以使用這個表達式:

/@@\[([^:]*):(\d*)\]/ 

此正則表達式假設名稱不包含:字符。

原來的正則表達式有2個問題:

  • 在端部的空間,],使第二提到不匹配後立即,因爲它是在輸入的結束。 (如果你刪除它,貪婪的量詞將吞噬整個輸入字符串。)
  • *(.*)匹配0或多個實例貪婪地,這意味着它將盡可能多的字符地匹配,直到下一個標記無法匹配,它會回溯並嘗試匹配下一個標記。這就是爲什麼如上所述刪除空間時整個輸入字符串會被吞噬的原因。

也可以解決你的正則表達式有點使它(從我上面提到的解決方案分開)工作:

/@@\[(.*?):(\d*)]/s 

m標誌和i標誌是無用的在這裏,所以我刪除他們。你從來沒有在你的正則表達式中使用^$,所以m標誌是無用的。 i標誌僅在正則表達式中存在字母時纔有用,在此情況並非如此。

我在這裏使用*?量詞,這是匹配0或更多的懶惰版本。它將盡可能少地匹配下一個要匹配的標記。

+0

因爲括號是定義整個標籤的內容,所以''(^ d *)'可以被檢測出來,即使在那裏,我也會去檢測'[^ \]]'而不是'[^:]'將會是用戶名中的':'。 – Backlin 2012-08-07 06:31:20

+0

@Backlin:我不確定用戶名格式。如果'''在用戶名中,那麼我不知道OP將如何解決混淆。 – nhahtdh 2012-08-07 06:41:22

+0

是的,你是對的。如果你使用'[^:]'冒號不能在用戶名中允許,並且如果你使用'[^ ​​\]]'括號不能被允許。但我想這些角色都不應該被允許,以避免這樣的問題。 – Backlin 2012-08-07 07:40:40