gpt4 book ai didi

php - 查找并替换文本 block 中的 URL,但排除链接标记中的 URL

转载 作者:可可西里 更新时间:2023-10-31 23:48:34 25 4
gpt4 key购买 nike

我一直在尝试遍历一个字符串并查找 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\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?!',
function ($matches) {
return strpos(trim($matches[0]), 'thisone.com') == FALSE ?
'<a href="' . ltrim($matches[0], " \t\n\r\0\x0B.,@?^=%&amp;:/~\+#'") . '" rel="nofollow" target="_blank">' . ltrim($matches[0], "\t\n\r\0\x0B.,@?^=%&amp;:/~\+#'") . '</a>' :
'<a href="' . ltrim($matches[0], " \t\n\r\0\x0B.,@?^=%&amp;:/~\+#'") . '">' . ltrim($matches[0], "\t\n\r\0\x0B.,@?^=%&amp;:/~\+#'") . '</a>';
},
$body_str
);

到目前为止,我发现的几个问题是它倾向于在 'http' 等之前立即获取字符,例如一个空格/逗号/冒号等,它破坏了链接。因此,我使用 preg_replace_callback 来解决这个问题并删除一些会破坏链接的不需要的字符。

另一个问题是,为了避免通过匹配 url 破坏链接,这些 url 已经在 A 标签中,我目前排除了以引号、双引号开头的 url,我宁愿使用 href='|href="排除。

任何提示和建议将不胜感激

最佳答案

首先,我允许自己对您的代码进行一些重构,使其更易于阅读和修改:

function urltrim($str) {   return ltrim($str, " \t\n\r\0\x0B.,@?^=%&:/~\+#'");}function addlink($str,$nofollow=true) {        return '<a href="' . urltrim($str) . '"'.($nofollow ? ' rel="nofollow" target="_blank"' : '').'>' . urltrim($str) . '</a>';}function checksite($str) {        return 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\-\@?^=%&/~\+#])?!',       function ($matches) {        return checksite($matches[0]);    },    $body_str);

在那之后我改变了你处理链接的方式:

  • 我认为 URL 是一个单词(= 所有字符,直到找到空格或\n 或\t (=\s))
  • 我改变了匹配方式来匹配字符串前面是否存在href=
    • 如果它存在那么我什么都不做,它已经是一个链接
    • 如果不存在 href=,则替换链接
  • 所以 urltrim 方法不再有用了,因为我没有吃掉 http 之前的第一个字符
  • 当然,我使用 urlencode 对 url 进行编码并避免 html 注入(inject)
function urltrim($str) {    return $str;}function addlink($str,$nofollow=true) {        $url = preg_replace("#(https?)%3A%2F%2F#","$1://",urlencode(urltrim($str)));        return '<a href="' . $url . '"'.($nofollow ? ' rel="nofollow" target="_blank"' : '').'>' . urltrim($str) . '</a>';}function checksite($str) {        return 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]+)!',    function ($matches) {        if ($matches[1]) {            # If href= is present, dont do anything, return the original string            return $matches[0];        } else {            # add the previous char (" or ') and the link            return $matches[2].checksite($matches[3]);        }    },    $body_str);

希望这对您的项目有所帮助。告诉我们是否有帮助。

再见。

关于php - 查找并替换文本 block 中的 URL,但排除链接标记中的 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18123873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com