我使用正则表达式在 Twitter 流中使用以下 PHP 代码检测
@replies
。在第一个模式中,我替换了字符串开头的@replies;在第二个中,我替换了空格后的@replies。
$text = preg_replace('!^@([A-Za-z0-9_]+)!', '<a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);
$text = preg_replace('! @([A-Za-z0-9_]+)!', ' <a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);
我怎样才能最好地结合这两个规则而不会错误标记
[email protected]
作为回复?
好吧,再想一想,不标记 whatever@email 意味着前一个元素必须是“非单词”项目,因为可以包含在单词中的任何其他元素都可以作为电子邮件发出信号,所以它会铅:
!(^|\W)@([A-Za-z0-9_]+)!
但是你必须使用 $2 而不是 $1.
由于
^
不必站在RE的开头,您可以使用分组和|
来组合这些RE。
如果你不想重新插入你捕获的空白,你必须使用“正向后视”:
$text = preg_replace('/(?<=^|\s)@(\w+)/',
'<a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);
或“负面回顾”:
$text = preg_replace('/(?<!\S)@(\w+)/',
'<a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);
...无论你觉得哪个更容易理解。
这是我做组合的方法
$text = preg_replace('!(^| )@([A-Za-z0-9_]+)!', '$1<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
在非捕获组中使用交替,如果使用
\K
匹配则忘记空格。
使用
(\w+)
捕获字母数字和下划线字符。
完整的字符串匹配将保留
@
.@
. 之后的文本
代码:(演示)
echo preg_replace(
'/(?:^| \K)@(\w+)/',
'<a href="http://twitter.com/$1" target="_blank">$0</a>',
$tweet
);
$text = preg_replace('/(^|\W)@(\w+)/', '<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
preg_replace('%(?<!\S)@([A-Za-z0-9_]+)%', '<a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);
(?<!\S)
被粗略地翻译为“前面没有非空白字符”。有点双重否定,但也适用于字符串/行的开头。
这不会消耗任何前面的字符,不会使用任何捕获组,也不会匹配像
"[email protected]"
这样的字符串,这是一个有效的电子邮件地址。
测试:
Input = 'foo bar [email protected] bee @def goo@doo @woo'
Output = 'foo bar [email protected] bee <a href="http://twitter.com/def" target="_blank">@def</a> goo@doo <a href="http://twitter.com/woo" target="_blank">@woo</a>'
Hu,伙计们,不要推得太远......在这里:
!^\s*@([A-Za-z0-9_]+)!
我认为你可以使用交替,: 所以寻找字符串或空格的开头
'!(?:^|\s)@([A-Za-z0-9_]+)!'