PHP正则表达式URL解析问题preg_replace

时间:2013-05-07 05:01:34

标签: php regex preg-replace

我有一个自定义标记解析功能,多年来一直运行良好。我最近发现了一个我之前没有注意到的错误,但是我无法修复它。如果有人能帮助我,这将是非常棒的。所以我有一个定制的论坛和基于文本的MMORPG,每个输入都被清理和解析为bbcode,如标记。它还会解析URL并将它们变成合法的链接,这些链接会转到退出页面,并带有您要离开网站的免责声明......所以我遇到的问题是当我的用户在一个网站上发布多个网址时文本框(让我们说\ n分隔)它只会将每个其他URL转换为链接。这是URL的解析器:

$markup = preg_replace("/(^|[^=\"\/])\b((\w+:\/\/|www\.)[^\s<]+)" . "((\W+|\b)([\s<]|$))/ei", '"$1<a href=\"out.php?".shortURL("$2")."\" target=\"_blank\">".shortURL("$2")."</a>$4"', $markup);

正如你所看到它调用PHP函数,但这不是问题。然后整个文本块同时传递到这个preg_replace,而不是逐行或任何其他方式。

  1. 如果有更简单的方法来编写这个preg_replace,请告诉我
  2. 如果你能弄明白为什么这只是解析所有其他网址,那么这就是我的最终目标
  3. INPUT示例:

    http://skylnk.co/tRRTnb
    http://skylnk.co/hkIJBT
    http://skylnk.co/vUMGQo 
    http://skylnk.co/USOLfW 
    http://skylnk.co/BPlaJl 
    http://skylnk.co/tqcPbL
    http://skylnk.co/jJTjRs
    http://skylnk.co/itmhJs
    http://skylnk.co/llUBAR
    http://skylnk.co/XDJZxD
    

    示例输出:

    <a href="out.php?http://skylnk.co/tRRTnb" target="_blank">http://skylnk.co/tRRTnb</a>
    <br>http://skylnk.co/hkIJBT
    <br><a href="out.php?http://skylnk.co/vUMGQo" target="_blank">http://skylnk.co/vUMGQo</a> 
    <br>http://skylnk.co/USOLfW 
    <br><a href="out.php?http://skylnk.co/BPlaJl" target="_blank">http://skylnk.co/BPlaJl</a> 
    <br>http://skylnk.co/tqcPbL
    <br><a href="out.php?http://skylnk.co/jJTjRs" target="_blank">http://skylnk.co/jJTjRs</a>
    <br>http://skylnk.co/itmhJs
    <br><a href="out.php?http://skylnk.co/llUBAR" target="_blank">http://skylnk.co/llUBAR</a>
    <br>http://skylnk.co/XDJZxD
    <br>
    

1 个答案:

答案 0 :(得分:1)

e中的

preg_replace标记为deprecated。您可以使用preg_replace_callback访问相同的功能。

i标志在这里没用,因为\w已经匹配大写和小写,并且模式中没有反向引用。

我设置m标志,这使得^$匹配一行的开头和结尾,而不是整个字符串的开头和结尾。这应该可以解决你每隔一行匹配的奇怪问题。

我还使一些群组非捕获(?:pattern) - 因为较大的捕获群已经捕获了文本。

以下代码未经过测试。我只在regex测试器上测试了正则表达式。

preg_replace_callback(
    "/(^|[^=\"\/])\b((?:\w+:\/\/|www\.)[^\s<]+)((?:\W+|\b)(?:[\s<]|$))/m",
    function ($m) {
        return "$m[1]<a href=\"out.php?".shortURL($m[2])."\" target=\"_blank\">".shortURL($m[2])."</a>$m[3]";
    },
    $markup
);