我有一个自定义标记解析功能,多年来一直运行良好。我最近发现了一个我之前没有注意到的错误,但是我无法修复它。如果有人能帮助我,这将是非常棒的。所以我有一个定制的论坛和基于文本的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,而不是逐行或任何其他方式。
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>
答案 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
);