【发布时间】:2015-12-01 23:30:40
【问题描述】:
我正在尝试用preg_replace 解析包含& 的URL。
$content = preg_replace('#https?://[a-z0-9._/\?=&-]+#i', '<a href="$0" target="_blank">$0</a>', $content);
但是我是给用户cmets用的,所以我也在用htmlspecialchars()函数来防止XSS。
function formatContributionContent($content)
{
$content = nl2br(htmlspecialchars($content));
// Regexp for mails
$content = preg_replace('#[a-z0-9._-]+@[a-z0-9._&-]{2,}\.[a-z]{2,4}#', '<a href="mailto:$0">$0</a>', $content);
// Regexp for urls
$content = preg_replace('#https?://[a-z0-9._/\?=&-]+#i', '<a href="$0" target="_blank">$0</a>', $content);
var_dump($content);
}
formatContributionContent('https://openclassrooms.com/index.php?page=3&skin=blue');
而 htmlspecialchars 将& 转换为"&amp;",所以我的正则表达式会产生错误的结果。确实,使用以下 URL。
http://www.siteduzero.com/index.php?page=3&skin=blue
我得到;
<a href="https://openclassrooms.com/index.php?page=3&" target="_blank">https://openclassrooms.com/index.php?page=3&</a>;skin=blue
【问题讨论】:
-
你不能指望你的正则表达式能神奇地修复你在移交之前修改的内容。相反,您首先 必须进行替换,然后然后 可能使用
htmlspecialchars()方法来输出结果。但可能您必须将其应用于该 URL 的单独部分,而不是整个 URL,因为它显然会将 URL 转换为其可读符号,而不是以可用的方式呈现它。所以你的整个方法都行不通。您必须先拆分该 URL 并分别处理令牌。 -
我想把 url 转换成用户 cmets 中的链接。
-
假设您不希望呈现来自用户输入的任何 HTML 标记,您需要使用正则表达式来挑选电子邮件和链接的位置,然后使用它来标记输入。任何不是电子邮件或链接的东西都将被实体转义,电子邮件和链接被放入锚点,然后我们将它们合并在一起。 (我在这里说的是对arkascha所说的详细说明)
标签: php html regex preg-replace