首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使url正则表达式全局

使url正则表达式全局
EN

Stack Overflow用户
提问于 2012-09-10 21:21:21
回答 2查看 371关注 0票数 2

我一直在寻找一个正则表达式来替换字符串中的纯文本url(字符串可以包含多个url),方法是:

代码语言:javascript
复制
 <a href="url">url</a>

我发现了这个:http://mathiasbynens.be/demo/url-regex

我想使用diegoperini的regex (根据测试是最好的):

代码语言:javascript
复制
_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS

但我想让它全局替换字符串中的所有url。当我使用这个的时候:

代码语言:javascript
复制
/_(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?_iuS/g

它不工作,我如何使这个正则表达式是全局的,开头的下划线和结尾的"_iuS“是什么意思?

我想在php中使用它,所以我使用:

代码语言:javascript
复制
preg_replace($regex, '<a href="$0">$0</a>', $examplestring);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-10 21:43:17

下划线是正则表达式分隔符,i、u和S是模式修饰符:

I (PCRE_CASELESS)

如果设置了此修饰符,则模式中的字母将同时匹配大小写字母。

U (PCRE_UNGREEDY)

这个修饰符颠倒了量词的“贪婪”,因此它们在缺省情况下不是贪婪的,但如果后面跟着?,它们就会变得贪婪。它与Perl不兼容。它也可以通过模式中的(?U)修饰符设置或通过量词后面的问号(例如.*?)来设置。

S

当一个模式要被多次使用时,值得花更多的时间来分析它,以加快匹配所需的时间。如果设置了此修饰符,则会执行此额外分析。目前,学习模式只对没有单个固定起始字符的非锚定模式有用。

有关更多信息,请参阅http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

当您添加/ ... /g时,您添加了另一个正则表达式分隔符加上修饰符g,这就是它不起作用的原因。

票数 0
EN

Stack Overflow用户

发布于 2013-01-19 09:33:38

我同意@verdesmarald,并在以下函数中使用了此模式:

代码语言:javascript
复制
$string = preg_replace_callback(
        "_(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?_iuS",
        create_function('$match','
            $m = trim(strtolower($match[0]));
            $m = str_replace("http://", "", $m);
            $m = str_replace("https://", "", $m);
            $m = str_replace("ftp://", "", $m);
            $m = str_replace("www.", "", $m);

            if (strlen($m) > 25)
            {
                $m = substr($m, 0, 25) . "...";
            }

            return "<a href=\"$match[0]\">$m</a>";
                '), $string);

    return $string;

它似乎起到了作用,并解决了我遇到的一个问题。正如@verdesmarald所说,删除^和$字符使模式即使在我的pre_replace_callback()中也可以工作。

我唯一关心的是模式的效率有多高。如果在繁忙/高流量的web应用中使用,会不会造成瓶颈?

更新

如果在url的路径部分的末尾有一个尾迹点,那么上面的正则表达式模式就会中断,比如http://www.mydomain.com/page.。为了解决这个问题,我修改了正则表达式模式的最后部分,添加了^.,使最后部分看起来像[^\s^.]。在我读它的时候,不要匹配尾随的空格或点。

到目前为止,在我的测试中,它似乎工作得很好。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12352635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档