RegEx 将文本中的 URL 转换为带有自定义锚文本的可点击 URL

发布于 2024-12-05 09:54:39 字数 1380 浏览 0 评论 0原文

可能的重复:
需要一个好的正则表达式将 URL 转换为链接,但保留现有链接

这是我的示例输入:

http://www.website.com/1/
Click here http://www.website.com/2/ or visit the website: http://www.website.com/3/
or http://www.website.com/4/
http://www.website.com/5/

我想要一个 PHP 函数,将文本内的 URL 转换为标签,如下所示:

<a href="http://www.website.com/1/">http://www.website.com/1/</a>
Click <a href="http://www.website.com/2/">here</a> or visit the website: <a href="http://www.website.com/3/">http://www.website.com/3/</a>
or <a href="http://www.website.com/4/">http://www.website.com/4/</a>
<a href="http://www.website.com/5/">http://www.website.com/5/</a>

第 2 行有一个陷阱:如果URL 前面有单词 here,那么该单词应该用作锚文本。我需要在 PHP 中执行此操作。我认为 preg_replace 与 /e 开关可能会帮助我完成这项任务,但我不确定。这是我迄今为止使用的(借用的)正则表达式:

preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a    href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
//                     ^---- I've tried adding "|here "
//                           But I cannot get the order of \\1 and \\2 right

请提出建议。

Possible Duplicate:
Need a good regex to convert URLs to links but leave existing links alone

This is a my sample input:

http://www.website.com/1/
Click here http://www.website.com/2/ or visit the website: http://www.website.com/3/
or http://www.website.com/4/
http://www.website.com/5/

I want a PHP function that converts the URLs inside the text into tags, like so:

<a href="http://www.website.com/1/">http://www.website.com/1/</a>
Click <a href="http://www.website.com/2/">here</a> or visit the website: <a href="http://www.website.com/3/">http://www.website.com/3/</a>
or <a href="http://www.website.com/4/">http://www.website.com/4/</a>
<a href="http://www.website.com/5/">http://www.website.com/5/</a>

There is a catch on line 2: if the URL is preceded by the word here then the word should be used as the anchor text instead. I need to do this in PHP. I think preg_replace with /e switch might help me accomplish this task but I am not sure. This is the (borrowed) regex I've used so far:

preg_replace("#(^|[\n ])([\w]+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)#is", "\\1<a    href=\"\\2\" target=\"_blank\">\\2</a>", $ret);
//                     ^---- I've tried adding "|here "
//                           But I cannot get the order of \\1 and \\2 right

Please advice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江城子 2024-12-12 09:54:39

“但是我无法得到 \1 和 \2 的正确顺序”

捕获组的数量按照左括号的顺序排列,因此第一个左括号始终是 $1。如果您不希望这样,请使用命名组

对于您的问题,您可以尝试这个正则表达式,

(?:(here)\s*|\b)(\w+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)

它将在 $1 中包含“here”,在 $2 中包含链接。如果找不到“here”,则 $1 为空。

请参阅 Regexr 上的此处

因此,您需要替换 $1 的内容。如果它是空的,则将匹配项替换为

<a href="$2">$2</a>

else

<a href="$2">$1</a>

我认为这应该可以使用 preg_replace_callback

"But I cannot get the order of \1 and \2 right"

The number of the capturing groups are in the order of the opening brackets, so the first opening bracket will always be $1. If you don't want that, use named groups.

For your problem you can try this regex

(?:(here)\s*|\b)(\w+?://[\w\#$%&~/.\-;:=,?@\[\]+]*)

It will have "here" in $1 and the link in $2. If "here" is not found then $1 is empty.

See it here on Regexr

So, then you need to replace dependent on the content of $1. If it is empty then replace the match with

<a href="$2">$2</a>

else with

<a href="$2">$1</a>

I think this should be possible using preg_replace_callback

ま柒月 2024-12-12 09:54:39

我发现这个。

听起来很有趣,以为我自己没有测试过,但我现在正在这样做。

课程是这样的:

class MakeItLink {
    protected function _link_www( $matches ) {
        $url = $matches[2];
        $url = MakeItLink::cleanURL( $url );
        if( empty( $url ) ) {
            return $matches[0];
        }
 
        return "{$matches[1]}<a href='{$url}'>{$url}</a>";
    }
 
    public function cleanURL( $url ) {
        if( $url == '' ) {
            return $url;
        }
 
        $url = preg_replace( "|[^a-z0-9-~+_.?#=!&;,/:%@$*'()x80-xff]|i", '', $url );
        $url = str_replace( array( "%0d", "%0a" ), '', $url );
        $url = str_replace( ";//", "://", $url );
 
        /* If the URL doesn't appear to contain a scheme, we
         * presume it needs http:// appended (unless a relative
         * link starting with / or a php file).
         */
        if(
            strpos( $url, ":" ) === false
            && substr( $url, 0, 1 ) != "/"
            && !preg_match( "|^[a-z0-9-]+?.php|i", $url )
        ) {
            $url = "http://{$url}";
        }
 
        // Replace ampersans and single quotes
        $url = preg_replace( "|&([^#])(?![a-z]{2,8};)|", "&$1", $url );
        $url = str_replace( "'", "'", $url );
 
        return $url;
    }
 
    public function transform( $text ) {
        $text = " {$text}";
 
        $text = preg_replace_callback(
            '#(?])(\()?([\w]+?://(?:[\w\\x80-\\xff\#$%&~/\-=?@\[\](+]|[.,;:](?![\s<])|(?(1)\)(?![\s<])|\)))*)#is',
            array( 'MakeItLink', '_link_www' ),
            $text
        );
 
        $text = preg_replace( '#(<a>]+?>|>))<a>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $text );
        $text = trim( $text );
 
        return $text;
    }
}

使用非常简单,只需加载您要搜索的文本即可
链接并调用转换方法:

$text = MakeItLink::transform( $text );

所有这些代码均来自 WordPress,并已获得许可
通用公共许可证

I found this.

It sounds interesting, thought I have NOT tested it myself, I'm doing it now though.

The class goes like this:

class MakeItLink {
    protected function _link_www( $matches ) {
        $url = $matches[2];
        $url = MakeItLink::cleanURL( $url );
        if( empty( $url ) ) {
            return $matches[0];
        }
 
        return "{$matches[1]}<a href='{$url}'>{$url}</a>";
    }
 
    public function cleanURL( $url ) {
        if( $url == '' ) {
            return $url;
        }
 
        $url = preg_replace( "|[^a-z0-9-~+_.?#=!&;,/:%@$*'()x80-xff]|i", '', $url );
        $url = str_replace( array( "%0d", "%0a" ), '', $url );
        $url = str_replace( ";//", "://", $url );
 
        /* If the URL doesn't appear to contain a scheme, we
         * presume it needs http:// appended (unless a relative
         * link starting with / or a php file).
         */
        if(
            strpos( $url, ":" ) === false
            && substr( $url, 0, 1 ) != "/"
            && !preg_match( "|^[a-z0-9-]+?.php|i", $url )
        ) {
            $url = "http://{$url}";
        }
 
        // Replace ampersans and single quotes
        $url = preg_replace( "|&([^#])(?![a-z]{2,8};)|", "&$1", $url );
        $url = str_replace( "'", "'", $url );
 
        return $url;
    }
 
    public function transform( $text ) {
        $text = " {$text}";
 
        $text = preg_replace_callback(
            '#(?])(\()?([\w]+?://(?:[\w\\x80-\\xff\#$%&~/\-=?@\[\](+]|[.,;:](?![\s<])|(?(1)\)(?![\s<])|\)))*)#is',
            array( 'MakeItLink', '_link_www' ),
            $text
        );
 
        $text = preg_replace( '#(<a>]+?>|>))<a>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $text );
        $text = trim( $text );
 
        return $text;
    }
}

It’s very easy to use, just load up the text you want to search for
link and call the transform method:

$text = MakeItLink::transform( $text );

All of this code came out of WordPress, which is licensed under the
GPL

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文