regex 将tweet文本中的@replies替换为HTML超链接,而不替换电子邮件地址

t9eec4r0  于 2023-05-08  发布在  其他
关注(0)|答案(8)|浏览(358)

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

qqrboqgw

qqrboqgw1#

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

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

但你得用2美元而不是1美元

tvmytwxo

tvmytwxo2#

由于^不必位于RE的开头,因此您可以使用分组和|来合并这些RE。
如果你不想重新插入你捕获的空白,你必须使用“积极的lookbehind”:

$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);

你觉得更容易理解的

vjrehmav

vjrehmav3#

我是这样做的

$text = preg_replace('!(^| )@([A-Za-z0-9_]+)!', '$1<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
5f0d552i

5f0d552i4#

在非捕获组中使用交替,如果使用\K匹配,则忽略空格。
使用(\w+)捕获字母数字和下划线字符。
全字符串匹配将保留@
捕获组1将包含@之后的文本。
代码:(Demo

echo preg_replace(
         '/(?:^| \K)@(\w+)/',
         '<a href="http://twitter.com/$1" target="_blank">$0</a>',
         $tweet
     );
fjnneemd

fjnneemd5#

$text = preg_replace('/(^|\W)@(\w+)/', '<a href="http://twitter.com/$2" target="_blank">@$2</a>', $text);
0md85ypi

0md85ypi6#

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>'
vq8itlhq

vq8itlhq7#

小胡,你们别太过分了……这就是:

!^\s*@([A-Za-z0-9_]+)!
hwazgwia

hwazgwia8#

我想你可以用alternative,:查找字符串或空格的开头

'!(?:^|\s)@([A-Za-z0-9_]+)!'

相关问题