0

我有一个自定义标记解析功能,多年来一直运行良好。我最近发现了一个以前没有注意到的错误,并且我无法修复它。如果有人可以帮助我,那就太棒了。因此,我有一个自定义构建的论坛和基于文本的 MMORPG,并且每个输入都经过清理和解析以获取 bbcode 之类的标记。它还会解析 URL 并将它们变成合法链接,这些链接会转到退出页面,并带有免责声明,表明您将离开该站点......所以我遇到的问题是,当我用户在一个页面中发布多个 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. 如果你能弄清楚为什么这只是解析所有其他 URL,这就是我的最终目标

示例输入:

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>
4

1 回答 1

1

e标志 inpreg_replace弃用。您可以使用preg_replace_callback来访问相同的功能。

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

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

我还让一些组不捕获(?:pattern)- 因为更大的捕获组已经捕获了文本。

下面的代码未经测试。我只在正则表达式测试器上测试了正则表达式。

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
);
于 2013-05-08T04:22:16.083 回答