尝试用锚标记替换所有出现的@提及,到目前为止我有:
$comment = preg_replace('/@([^@ ])? /', '<a href="/$1">@$1</a> ', $comment);
采用以下示例字符串:
"@name kdfjd fkjd as@name @ lkjlkj @name"
到目前为止一切正常,但我想忽略那个单一的“@”符号。我尝试在“[^@]”之后使用“+”和“{2,}”,我认为这会强制执行最少数量的匹配,但它不起作用。
替换问号 ( ?
) 量词(“可选”)并+
在您的字符类别后添加一个(“一个或多个”):
@([^@ ]+)
正则表达式
(^|\s)(@\w+)
可能是你所追求的。
它基本上意味着,行首或空格,然后是 @ 符号,后跟 1 个或多个单词字符。
例如
preg_match_all('/(^|\s)(@\w+)/', '@name1 kdfjd fkjd as@name2 @ lkjlkj @name3', $result);
var_dump($result[2]);
给你
Array
(
[0] => @name1
[1] => @name3
)
我喜欢 Petah 的回答,但我稍微调整了一下
preg_replace('/(^|\s)@([\w.]+)/', '$1<a href="/users/$2">@$2</a>', $text);
主要区别在于:
@
符号不包括在内。仅用于显示,不应在 URL 中.
字符(注意:\w
包括下划线)$1
在开头添加以保留空格替换?
为+
将起作用,但不像您期望的那样。
@name
您的表达式在字符串末尾不匹配。
$comment = preg_replace('#@(\w+)#', '<a href="/$1">$0</a> ', $comment);
这应该做你想要的。\w+
代表字母 (a-zA-Z0-9)
我建议在匹配@
当时的一个或多个不是空格或@
.
“一个或多个”量词 ( +
)可防止匹配未提及 one 的提及。
使用lookbehind 是一个好主意,因为它不仅可以防止匹配电子邮件地址和其他此类不需要的子字符串,它还要求正则表达式引擎主要搜索@
s 然后检查前面的字符。这应该会提高模式性能,因为空格的数量应该始终超过评论中提及的数量。
如果输入文本是多行或可能包含换行符,则添加m
模式修饰符将告诉^
匹配所有行开头。如果可以使用换行符和制表符,则 is 使用起来会更可靠(?<=^|\s)@([^@\s]+)
。
代码:(演示)
$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>'
尝试:
'/@(\w+)/i'