【问题标题】:php regex - Replace all @usernames with link in a stringphp regex - 用字符串中的链接替换所有@usernames
【发布时间】:2015-11-21 15:01:39
【问题描述】:

我正在我的网站上实现一个时间线系统,用户可以使用 @username 在他们的时间线中提及其他用户,例如 twitter。

我想将 @username 转换为链接并将其指向他们的个人资料

我的字符串:

$timeline="@fred-ii 's posts on @stackoverflow are intresting."; 

我正在使用以下代码将 @username 替换为 url:

echo preg_replace("/@([^\s]+)/i","<a href='http://example.com/$1'>@$1</a>",$timeline);

它有效,问题是它也匹配空格

这个字符串

"@fred-ii 's posts on@stackoverflow";

on@stackoverflow之间没有空格,我要排除它,

所以我更新了我的正则表达式

/\s+@([^\s]+)/

它有效,但它与我的字符串的第一部分不匹配(用户名 @fred-ii )。我认为正则表达式引擎正在寻找字符串开头的空格。

我需要更改我的模式以匹配所有@usernames 吗?

$timeline="@fred-ii 's posts on @stackoverflow are intresting."; 

【问题讨论】:

  • 所以你想匹配用户名中的空格,但链接中没有空格?

标签: php regex preg-replace


【解决方案1】:

您可以使用lookbehind negative assertion

/(?<!\w)@([^\s]+)/

(?&lt;!\w) 告诉正则表达式引擎匹配 @([^\s]+),前提是它前面没有单词 \w。它将在您提供的示例中起作用,也许您必须随时对其进行调整。

示例代码:

$pattern = "/(?<!\w)@([^\s]+)/";
$subject = "@fred-ii 's posts on @stackoverflow are interesting. @fred-ii 's posts on@stackoverflow";

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER );

foreach($matches as $item)
{
    echo $item[1] . "<br/>";
}

产生这个输出:

fred-ii
stackoverflow
fred-ii

查看action

【讨论】:

    【解决方案2】:

    你可以使用这个lookbehind断言:

    /(?<=\s|^)@\S+/
    

    (?&lt;=\s|^) 确保@ 之前有空格或行开头。

    代码:

    php> $s = "@fred-ii 's posts on@stackoverflow";
    
    php> echo preg_replace('/(?<=\s|^)@\S+/', "<a href='http://example.com/$0'>$0</a>", $s);
    <a href='http://example.com/fred-ii'>@fred-ii</a> 's posts on@stackoverflow
    

    【讨论】:

    • Anubhava 你的答案是正确的,它给出了正确的输出。但是如果我不使用 lookbehind 例如模式 /(\s+|^)@([^\s]+)/ 也可以工作,是否正确使用它或总是向后看。请指导我。
    • 是的,您也可以使用:/(?:\s|^)@([^\s]+)/ 与捕获的组。 Lookbehind 让您可以选择根本不使用任何捕获的组:preg_replace('/(?&lt;=\s|^)@\S+/', "&lt;a href='http://example.com/$0'&gt;$0&lt;/a&gt;", $s);
    • Thank you 对 Anubhava 的解释非常了解,我从您的回答和评论中学到了很多关于 LookBehind 的知识。我真的很欣赏它。
    • Anubhava 你知道如何在基于 Shell 的通配符表达式中匹配字符串吗?很抱歉添加了不相关的评论,我很快就会删除它。
    • 试试:s="@fred-ii 's posts on@stackoverflow"; sed -r 's~(^|[[:blank:]])(@[^[:blank:]]+)~\1&lt;a href="http://example.com/\2"&gt;\2&lt;/a&gt;~' &lt;&lt;&lt; "$s"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2018-12-06
    • 1970-01-01
    • 2019-03-22
    • 2018-07-09
    • 1970-01-01
    • 2015-10-13
    相关资源
    最近更新 更多