【发布时间】:2011-05-22 09:24:03
【问题描述】:
我正在尝试找到一种可靠的解决方案来从字符串中提取 url。我有一个网站,用户可以在其中回答问题,并在来源框中输入他们的信息来源,我允许他们输入网址。我想提取该网址并使其成为超链接。类似于 Yahoo Answers 的做法。
有谁知道可以做到这一点的可靠解决方案吗?
我发现的所有解决方案都适用于某些 URL,但不适用于其他 URL。
谢谢
【问题讨论】:
标签: php regex url preg-replace
我正在尝试找到一种可靠的解决方案来从字符串中提取 url。我有一个网站,用户可以在其中回答问题,并在来源框中输入他们的信息来源,我允许他们输入网址。我想提取该网址并使其成为超链接。类似于 Yahoo Answers 的做法。
有谁知道可以做到这一点的可靠解决方案吗?
我发现的所有解决方案都适用于某些 URL,但不适用于其他 URL。
谢谢
【问题讨论】:
标签: php regex url preg-replace
John Gruber 拥有spent a fair amount of time 完善了“一个正则表达式来统治所有这些”以进行链接检测。使用preg_replace() 如其他答案中所述,使用以下正则表达式应该是检测链接的最准确(如果不是最准确)方法之一:
(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
如果你只想匹配 HTTP/HTTPS:
(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
【讨论】:
" 和 ' 代码不能正常工作,比如:preg_match('(?i)\b......]))', $str) - 所有代码似乎都被注释了。
$string = preg_replace('/https?:\/\/[^\s"<>]+/', '<a href="$0" target="_blank">$0</a>', $string);
它只匹配 http/https,但这确实是您想要转换为链接的唯一协议。如果你想要其他人,你可以这样改变它:
$string = preg_replace('/(https?|ssh|ftp):\/\/[^\s"]+/', '<a href="$0" target="_blank">$0</a>', $string);
【讨论】:
< 或在匹配的字符串上应用 htmlspecialchars 以避免代码注入。
" 之外的任何内容。我相信这消除了任何 HTML 注入。
url 有很多边缘情况。像 url 可以包含括号或不包含协议等。这就是为什么正则表达式是不够的。
我创建了一个可以处理大量边缘情况的 PHP 库:Url highlight。
您可以从字符串中提取网址或直接突出显示它们。
示例:
<?php
use VStelmakh\UrlHighlight\UrlHighlight;
$urlHighlight = new UrlHighlight();
// Extract urls
$urlHighlight->getUrls("This is example http://example.com.");
// return: ['http://example.com']
// Make urls as hyperlinks
$urlHighlight->highlightUrls('Hello, http://example.com.');
// return: 'Hello, <a href="http://example.com">http://example.com</a>.'
【讨论】:
雅虎!当链接写得正确并与其他文本分开时,Answers 可以很好地识别链接,但它不能很好地分离尾随标点符号。例如The links are @987654321@, @987654322@, and @987654323@. 将在前两个中包含逗号,在第三个中包含句点。
但如果这是可以接受的,那么像这样的模式应该这样做:
\<http:[^ ]+\>
看起来stackoverflow的解析器更好。是开源的吗?
【讨论】:
这段代码对我有用。
function makeLink($string){
/*** make sure there is an http:// on all URLs ***/
$string = preg_replace("/([^\w\/])(www\.[a-z0-9\-]+\.[a-z0-9\-]+)/i", "$1http://$2",$string);
/*** make all URLs links ***/
$string = preg_replace("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/i","<a target=\"_blank\" href=\"$1\">$1</a>",$string);
/*** make all emails hot links ***/
$string = preg_replace("/([\w-?&;#~=\.\/]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?))/i","<a href=\"mailto:$1\">$1</a>",$string);
return $string;
}
【讨论】: