用于匹配所有的PHP正则表达式模式

时间:2012-08-07 06:18:35

标签: php regex

我的应用程序中有类似facebook的提及功能。

创建帖子或评论时,用户可以使用@符号提及其他用户。 我使用以下jQuery插件:http://podio.github.com/jquery-mentions-input/

提及的格式如下: @@ [Marko 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,Marko

1 个答案:

答案 0 :(得分:2)

您可以使用此正则表达式:

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

此正则表达式假定该名称不包含:个字符。

原始正则表达式有两个问题:

  • 结尾处的空格,恰好在]之后,导致第二次提及无法匹配,因为它位于输入的末尾。 (如果删除它,贪婪的量词将吞噬整个输入字符串。)
  • *中的(.*)匹配0个或更多实例 贪婪 ,这意味着它将匹配尽可能多的字符,直到下一个令牌无法匹配,它将回溯并尝试匹配下一个令牌。这就是为什么如果你移除空间,整个输入字符串将被吞噬,如上所述。

也可以修改你的正则表达式以使它工作(除了我上面提到的解决方案):

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

此处m标志和i标志无效,因此我将其删除。您永远不会在正则表达式中使用^$,因此m标记无效。 i标志仅在正则表达式中有字母时才有用,这不是这里的情况。

我在这里使用*?量词,这是匹配0或更多的懒惰版本。它将匹配尽可能少的字符,仅用于下一个要匹配的标记。