我一直在尝试遍历一个字符串并找到并用一个链接替换 URL,这是我到目前为止所提出的,它似乎在大多数情况下工作得很好,但是有一些我想要的东西抛光。它也可能不是最好的执行方式。
我已经在 SO 上阅读了很多关于此的主题,尽管它有很大帮助,但我仍然需要解决它的松散问题。
我在字符串中运行了两次。我第一次用html标签替换bbtags;第二次我运行字符串并用链接替换文本网址:
$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="进行排除。
任何提示和建议将不胜感激
最佳答案
首先,我允许自己重构一下您的代码,使其更易于阅读和修改:
函数 urltrim($str) {
return ltrim($str, "\t\n\r\0\x0B.,@?^=%&:/~\+#'");
}
函数 addlink($str,$nofollow=true) {
返回 '';
}
功能检查站点($ str){
返回 strpos(trim($str), 'thisone.com') == FALSE ? addlink($str) : addlink($str,false);
}
$body_str = preg_replace('/\[url=(.+?)\](.+?)\[\/url\]/i', '\2', $body_str);
$body_str = preg_replace_callback(
'!(?:^|[^"\'])(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?!',
功能($匹配){
返回检查站点($matches[0]);
},
$body_str
);
之后我改变了你处理链接的方式:
函数 urltrim($str) {
返回 $str;
}
函数 addlink($str,$nofollow=true) {
$url = preg_replace("#(https?)%3A%2F%2F#","$1://",urlencode(urltrim($str)));
返回 '';
}
功能检查站点($ str){
返回 strpos(trim($str), 'thisone.com') == FALSE ? addlink($str) : addlink($str,false);
}
$body_str = preg_replace('/\[url=(.+?)\](.+?)\[\/url\]/i', '\2', $body_str);
$body_str = preg_replace_callback(
'!(|href=)(["\']?)(https?://[^\s]+)!',
功能($匹配){
如果 ($matches[1]) {
# 如果href=存在,不要做任何事情,返回原始字符串
返回 $matches[0];
} 别的 {
# 添加前一个字符("或 ')和链接
返回 $matches[2].checksite($matches[3]);
}
},
$body_str
);
我希望这可以帮助您完成您的项目。
告诉我们是否有帮助。
再见。
关于php - 查找和替换文本块中的 URL,但排除链接标签中的 URL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18123873/