我想说我在SO上有类似的问题,但由于我的情况略有不同,我认为开一个新问题会更好。我找了一个小时,我可能错过了一些东西,如果有的话请原谅我。
问题:我正在开发一个类似于facebook的功能:用户可以发布一条文本消息,其中可能包含许多链接,这些链接可能或许多不会放在锚标签中,并且可能有不同的协议(http,https ,ftp,....)
我需要
检测这些链接并尝试检索它们(就像facebook一样)。我想这是jquery的任务?
我还需要可靠地检测外部链接并将其更改为mysite.com/external?url=thelink。我认为,这是php的任务(因为我无法相信来自客户端的输入吗?)
无论如何,由于链接不能保证在锚标签中,使用dom解析器似乎不太可靠(或者我错了)? 我在网上发现了一个简单的正则表达式(我用regex btw很糟糕),我认为我可以利用它(通过添加更多协议)
$strText = preg_replace( '/(http|ftp)+(s)?:(\/\/)((\w|\.)+)(\/)?(\S+)?/i', '<a href="\0">\4</a>', $strText );
那些有经验的专家可以指出我正确的方向吗?
答案 0 :(得分:1)
是的,这绝对是你想要做服务器端的事情。首先,如果您接受包含HTML标记的用户输入,则应使用HTML Purifier之类的良好HTML过滤器对其进行清理。 (这也将使他们的输入更容易解析更复杂的标记。)
这个应该在单个preg_replace()语句中可行,但是我将它拆分成这样的东西:
$hrefPattern = '/<a[^>]+?href="(.+?)".*?>/i';
$outLink = 'http://mysite.com/external?url=';
$offset = 0;
while(preg_match($hrefPattern, $text, $hrefMatches, PREG_OFFSET_CAPTURE, $offset))
{
$hrefInner = $hrefMatches[1][0];
$offset = $hrefMatches[1][1];
echo $hrefInner . "\r\n";
if(strpos($hrefInner, '://') !== false)
{
$externalUrl = $outLink . rawurlencode($hrefInner);
$text = str_replace($hrefInner, $externalUrl, $text);
$offset += strlen($externalUrl);
}
}
preg_match() documentation很好地解释了这一点。我们基本上只是查找每个<a ... href="">
标记,抓取它的内容,如果它以(anything)://
开头,则重新格式化,然后重复直到$text
中没有剩余链接。如果您重新格式化该链接,则需要rawurlencode()
您抓取的链接,以确保新链接为valid。
Facebook为其链接片段抓取内容的方式,我认为,比这更复杂,但是是的 - 你想要发送一个AJAX请求到一个PHP页面,该页面会刮擦有问题的链接并生成无论你想要什么片段。虽然如果页面不存在,重新定向到另一个页面,具有无效标记,不同的文档类型等等,那么相当会更多地参与其中。 p>
希望有所帮助!