preg_replace不如预期工作

3
我写了一个简单的函数,它可以接受一段文本,从中提取URL,并将所有的URL替换为带有<a href>标签的链接。
例如:http://site.com应该变成<a href="http://site.com">http://site.com</a> 代码:
function parseUrls( $string )
{
    $string = trim($string);
    $pattern = '%\bhttp[s]?://[A-z0-9/\.\-_]+%i';
    $replacement = '<a href="$1">$1</a>';

    $string = preg_replace($pattern, $replacement, $string);

    return $string;
}

然而,如果我把以下字符串作为输入:

hello https://google.com test http://test.com/something.html abc http://site.com

我得到的输出是:

hello <a href=""></a> test <a href=""></a> abc <a href=""></a> 

也就是说,URL已经被匹配,但$replacement没有被正确应用。可能我的$1的使用方式有误?

我做错了什么?


您尚未设置任何捕获组。请尝试在您的 URL 匹配周围添加 (...)。 - Daniel M
2
我不得不给这个问题点赞,因为你的名字。我总是遵循指示。 - Matt
3个回答

6

你的表达式中没有定义捕获组(通常使用())。因此$1为空。但是在替换模式中,$0保存了完整的匹配字符串。

所以要么使用:

$replacement = '<a href="$0" target="_BLANK">$0</a>';

或者
$pattern = '%\b(http[s]?://[A-z0-9/\.\-_]+)%i';
//             ^                          ^
//             |                          |
//             +-----  Capture group -----+

3

你没有一个捕获组可以被引用为$1

请使用$replacement = '<a href="$0" target="_BLANK">$0</a>';代替。

另外,在你的字符类中不要使用A-z(它匹配的内容比你想象的多:在ASCII码中,Za之间有一些非字母字符)。既然你已经忽略了大小写,那么只使用A-Z就足够了。


1
感谢您在A-z上的发现。 - Ali

1

您需要使用括号将表达式分组,以便使用$1。

$pattern = '%\b(http[s]?://[A-z0-9/.-_]+)%i';


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接