-1

我正在使用正则表达式使用以下 PHP 代码在 Twitter 流中检测@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@domain.com 标记为回复?

4

7 回答 7

4

好的,再想一想,不标记任何@email 意味着前一个元素必须是“非单词”项目,因为可以包含在单词中的任何其他元素都可以被标记为电子邮件,所以它会导致:

!(^|\W)@([A-Za-z0-9_]+)!

但是你必须使用 $2 而不是 $1。

于 2009-02-09T21:17:30.173 回答
2

由于^不必位于 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);

...无论您发现哪个更容易理解。

于 2009-02-09T21:45:24.303 回答
0

这就是我将如何进行组合

$text = preg_replace('!(^| )@([A-Za-z0-9_]+)!', '$1<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
于 2009-02-09T21:15:45.063 回答
-1
preg_replace('%(?<!\S)@([A-Za-z0-9_]+)%', '<a href="http://twitter.com/$1" target="_blank">@$1</a>', $text);

(?<!\S)被松散地翻译为“没有前面的非空白字符”。有点双重否定,但也适用于字符串/行的开头。

这不会使用任何前面的字符,不会使用任何捕获组,并且不会匹配字符串,例如"foo-@host.com",它是一个有效的电子邮件地址。

测试:

Input = 'foo bar baz-@qux.com bee @def goo@doo @woo'
Output = 'foo bar baz-@qux.com bee <a href="http://twitter.com/def" target="_blank">@def</a> goo@doo <a href="http://twitter.com/woo" target="_blank">@woo</a>'
于 2009-02-09T21:26:31.980 回答
-1
$text = preg_replace('/(^|\W)@(\w+)/', '<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
于 2009-02-09T21:36:12.487 回答
-2

我认为您可以使用交替,:所以寻找字符串或空格的开头

'!(?:^|\s)@([A-Za-z0-9_]+)!'
于 2009-02-09T21:24:32.780 回答
-2

胡,伙计们,不要推得太远......这里是:

!^\s*@([A-Za-z0-9_]+)!
于 2009-02-09T21:28:53.987 回答