我一直在尝试遍历一个字符串并查找和替换URL链接,这是我迄今为止想出的方法,它似乎在很大程度上运行良好,但是还有一些需要改进的地方。此外,可能不是最佳性能的实现方式。
我在SO上阅读了许多关于此问题的帖子,虽然它对我有很大帮助,但我仍然需要解决其中的一些问题。
我通过两次遍历字符串来实现。第一次我用HTML标记替换bbtags;第二次我遍历字符串并用链接替换文本URL:
$body_str = preg_replace('/\[url=(.+?)\](.+?)\[\/url\]/i', '<a href="\1" rel="nofollow" target="_blank">\2</a>', $body_str);
$body_str = preg_replace_callback(
'!(?:^|[^"\'])(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?!',
function ($matches) {
return strpos(trim($matches[0]), 'thisone.com') == FALSE ?
'<a href="' . ltrim($matches[0], " \t\n\r\0\x0B.,@?^=%&:/~\+#'") . '" rel="nofollow" target="_blank">' . ltrim($matches[0], "\t\n\r\0\x0B.,@?^=%&:/~\+#'") . '</a>' :
'<a href="' . ltrim($matches[0], " \t\n\r\0\x0B.,@?^=%&:/~\+#'") . '">' . ltrim($matches[0], "\t\n\r\0\x0B.,@?^=%&:/~\+#'") . '</a>';
},
$body_str
);
到目前为止,我发现这个程序有一个问题,就是它倾向于捕捉到“http”之前的字符,例如空格/逗号/冒号等,这会导致链接断裂。因此,我使用preg_replace_callback来解决这个问题,并修剪一些可能破坏链接的不必要字符。
另一个问题是,为了避免匹配已经在A标签中的URL而破坏链接,我目前正在排除以引号或双引号开头的URL,并且我更愿意使用href='|href="进行排除。
非常感谢任何技巧和建议。