Php 使url正则表达式全局化

Php 使url正则表达式全局化,php,regex,url,Php,Regex,Url,我一直在搜索正则表达式来替换字符串中的纯文本url(该字符串可以包含多个url),方法是: 但是我想让它全局化,以替换字符串中的所有url。 当我使用此选项时: /_(?:(?: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[

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

但是我想让它全局化,以替换字符串中的所有url。 当我使用此选项时:

/_(?:(?: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一起使用,因此我使用:

preg_replace($regex, '<a href="$0">$0</a>', $examplestring);
preg_replace($regex,,$examplestring);

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

i(PCRE_无壳)

U(PCRE_UNGREEDY)

有关更多信息,请参阅


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

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

i(PCRE_无壳)

U(PCRE_UNGREEDY)

有关更多信息,请参阅


当您添加//g,您添加了另一个regex分隔符和修饰符g,因为它在PCRE中不存在。这就是为什么它不起作用。

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

$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;
$string=preg\u replace\u回调(
以下几种:::(以下以下以下以下以下::::::::::::::::::::::::::::::::(以下::::::(以下::::::::::::::::::::::(::::::::::::::::::::::{{1,3})3{{3})3},(:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::(((!(((::::::::::::::::::::::::::::::::::::::::::::::::(2)(1-9)(1-9)(1-9)(22)(0-3)(1-9)(1-9)(2)(0-4)(25()))))(((:(a-z-x)25))0-4)))))))))()){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,})(?:)(?:[a-z\x{00a1}-\x}-\x{ffff}-\2,5})/[U]],
创建函数('$match','
$m=修剪(strtolower($match[0]);
$m=str_replace(“http:/”、“”、$m);
$m=str_replace(“https:/”、“”、$m);
$m=str_replace(“ftp://”,“”,$m);
$m=str_替换(“www.,”,$m);
如果(斯特伦(百万美元)>25)
{
$m=substr($m,0,25)。“…”;
}
返回“”;
“),$string);
返回$string;
它似乎做到了这一点,解决了我遇到的一个问题。正如@verdesmarald所说,删除“^”和“$”字符使该模式即使在我的pre_replace_回调()中也能工作

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

更新

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


到目前为止,在我的测试中,它似乎运行良好。

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

$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;
$string=preg\u replace\u回调(
以下几种:::(以下以下以下以下以下::::::::::::::::::::::::::::::::(以下::::::(以下::::::::::::::::::::::(::::::::::::::::::::::{{1,3})3{{3})3},(:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::(((!(((::::::::::::::::::::::::::::::::::::::::::::::::(2)(1-9)(1-9)(1-9)(22)(0-3)(1-9)(1-9)(2)(0-4)(25()))))(((:(a-z-x)25))0-4)))))))))()){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,})(?:)(?:[a-z\x{00a1}-\x}-\x{ffff}-\2,5})/[U]],
创建函数('$match','
$m=修剪(strtolower($match[0]);
$m=str_replace(“http:/”、“”、$m);
$m=str_replace(“https:/”、“”、$m);
$m=str_replace(“ftp://”,“”,$m);
$m=str_替换(“www.,”,$m);
如果(斯特伦(百万美元)>25)
{
$m=substr($m,0,25)。“…”;
}
返回“”;
“),$string);
返回$string;
它似乎做到了这一点,解决了我遇到的一个问题。正如@verdesmarald所说,删除“^”和“$”字符使该模式即使在我的pre_replace_回调()中也能工作

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

更新

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


到目前为止,在我的测试中,它似乎运行良好。

对不起,我不明白,最后一条评论,定义是什么?
preg\u replace
默认替换所有出现的内容,您应该能够删除
^
$
锚。是的,您是对的,我使用了这样的url:www.google.pt,作为tex中的第二个urlt字符串,我认为它没有被替换,因为它只是替换了第一个匹配项,但结果是正则表达式与URL不匹配。很抱歉,我不明白,最后一条评论,定义是什么?
preg\u replace
默认替换所有出现的内容,您应该能够删除
^
$
锚定s、 是的,你是对的,我使用了这样一个url:www.google.pt,作为文本字符串中的第二个url,我认为它没有被替换,因为它只是替换了第一个匹配项,但结果是正则表达式与url不匹配。请将此作为你问题的自我回答,而不是这个问题。@nhahtdh现在我不会,因为我发现,通过进一步测试,当遇到url和粗体结束标记时,这种模式也会中断,如:
http://mydomain/contact
If this modifier is set, letters in the pattern match both upper and lower 
case letters.
This modifier inverts the "greediness" of the quantifiers so that they are 
not greedy by default, but become greedy if followed by ?. It is not compatible
with Perl. It can also be set by a (?U) modifier setting within the pattern 
or by a question mark behind a quantifier (e.g. .*?).
When a pattern is going to be used several times, it is worth spending more 
time analyzing it in order to speed up the time taken for matching. If this 
modifier is set, then this extra analysis is performed. At present, studying 
a pattern is useful only for non-anchored patterns that do not have a single 
fixed starting character.
$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;