在字符串中查找@mentions

时间:2012-04-30 12:59:28

标签: php regex

尝试用锚标记替换所有出现的@mention,到目前为止我有:

$comment = preg_replace('/@([^@ ])? /', '<a href="/$1">@$1</a> ', $comment);

采取以下示例字符串:

"@name kdfjd fkjd as@name @ lkjlkj @name"

到目前为止,所有内容都匹配,但我想忽略那个单独的“@”符号。我尝试在“[^ @]”之后使用“+”和“{2,}”,我认为它会强制执行最少量的匹配,但它不起作用。

6 个答案:

答案 0 :(得分:8)

替换问号(?)量词(&#34;可选&#34;)并在角色类后添加+(&#34;一个或多个&#34;) :

@([^@ ]+)

答案 1 :(得分:6)

正则表达式

(^|\s)(@\w+)

你可能会追求自己。

它基本上是指行的开头或空格,然后是@符号后跟1个或多个单词字符。

E.g。

preg_match_all('/(^|\s)(@\w+)/', '@name1 kdfjd fkjd as@name2 @ lkjlkj @name3', $result);
var_dump($result[2]);

给你

Array
    (
        [0] => @name1
        [1] => @name3
    )

答案 2 :(得分:3)

我喜欢Petah的回答,但我稍微调整了一下

preg_replace('/(^|\s)@([\w_\.]+)/', '$1<a href="/users/$2">@$2</a>', $text);

主要区别是:

  • 不包含@符号。仅供显示的内容不应位于网址
  • 还允许_.符号
  • 在替换中,我在开头添加$1以保留空白

答案 3 :(得分:2)

?替换+会有效,但不会像预期的那样。

您的表达式与字符串末尾的@name不匹配。

$comment = preg_replace('#@(\w+)#', '<a href="/$1">$0</a> ', $comment);

这应该做你想要的。 \w+代表字母(a-zA-Z0-9)

答案 4 :(得分:1)

我建议在匹配@然后使用一个或多个不是空格或@的字符之前先使用后置字符。

“一个或多个”量词(+防止匹配没有提及的提及

使用后向搜索是一个好主意,因为它不仅防止电子邮件地址和其他此类不需要的子字符串匹配,而且还要求正则表达式引擎首先搜索@,然后检查前一个字符。这将提高模式性能,因为空格数应始终超过注释中的提及数。

如果输入文本为多行或可能包含换行符,则添加m模式修饰符将告诉^匹配所有行首。如果可以使用换行符和制表符,则使用(?<=^|\s)@([^@\s]+)会更可靠。

代码:(Demo

$comment = "@name kdfjd @@ fkjd as@name @ lkjlkj @name";

var_export(
    preg_replace(
        '/(?<=^| )@([^@ ]+)/',
        '<a href="/$1">@$1</a>',
        $comment
    )
);

输出:(单引号来自var_export()

'<a href="/name">@name</a> kdfjd @@ fkjd as@name @ lkjlkj <a href="/name">@name</a>'

答案 5 :(得分:0)

尝试:

'/@(\w+)/i'