Php 从字符串中提取URL

Php 从字符串中提取URL,php,regex,url,preg-replace,Php,Regex,Url,Preg Replace,我正试图找到一个可靠的解决方案,从字符串中提取url。我有一个网站,用户可以在其中回答问题,在“源”框中输入信息源,我允许他们输入url。我想提取该url并使其成为超链接。类似于雅虎的回答方式 有人知道一个可靠的解决方案可以做到这一点吗 我发现的所有解决方案都适用于某些URL,但不适用于其他URL 谢谢雅虎!当链接书写正确且与其他文本分开时,Answers在链接识别方面做得相当好,但在分离尾随标点符号方面做得不是很好。例如,链接是,并且。在前两个链接上包含逗号,在第三个链接上包含句点 但如果这是

我正试图找到一个可靠的解决方案,从字符串中提取url。我有一个网站,用户可以在其中回答问题,在“源”框中输入信息源,我允许他们输入url。我想提取该url并使其成为超链接。类似于雅虎的回答方式

有人知道一个可靠的解决方案可以做到这一点吗

我发现的所有解决方案都适用于某些URL,但不适用于其他URL

谢谢

雅虎!当链接书写正确且与其他文本分开时,Answers在链接识别方面做得相当好,但在分离尾随标点符号方面做得不是很好。例如,
链接是,并且。
在前两个链接上包含逗号,在第三个链接上包含句点

但如果这是可以接受的,那么像这样的模式应该可以做到:

\<http:[^ ]+\>
\
看起来stackoverflow的解析器更好。是开源的吗?

$string=preg\u replace('/https?:\/\/[^\s“]+/',''$string);
$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);
$string=preg\u replace('/(https?| ssh | ftp):\/\/[^\s“]+/”,''$string);
John Gruber完善了链接检测的“一个正则表达式来管理所有正则表达式”。使用其他答案中提到的
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`!()\[\]{};:'".,<>?«»“”‘’]))
(2)以下两种(以下简称:::[a-z[a-z[[a-z[[[w-[w-[[w-[[[w-[[[w-[[w-[[[w-[[a-a-z[[a-z[[a-a-z[a-z[[[[w-[w-[[[[w-[[[[[C-z0-z0-9-10-10-10-9-10-9-9%[9-9-9-9%[9%[9%]]]]))))))))))))以下以下以下两个(以下以下以下两个::::::::::)以下以下以下以下以下((((())))))的((((())))))在(以下以下两个((((()))))两个(以下以下以下以下以下以下)两个((((()))){};:“,«»””)) 如果您只想匹配HTTP/HTTPS:

(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))
(?i)/b((?:https?:/)(?:[^\s()]+)*)+(?:([^\s())+)+(([^\s())+)*)+(([^\s())+)+([^\s())+([^\s())+(([^\s())+)+(?:(([^\s()+)+)(^\s())+)+(^-+)+)+(^-+)+(^-+)+(^-+)+(^-+)+)+(^-+)*)+(^-(^-+)+)+)+(^-(^-+)+)+)+(^-(^-)+)+)+)+(^-(^-)+)+(^-(^-)+)+)+)+

此代码为我工作

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;
}
函数makeLink($string){
/***确保所有URL上都有http://链接***/
$string=preg\u replace(“/([^\w\/])(www\.[a-z0-9\-]+\.[a-z0-9\-]+)/i“,“$1http://$2”,$string);
/***创建所有URL链接***/
$string=preg\u replace(“/([\w]+:\/\/[\w-?&;\\.\/\@]+[\w\/])/i“,”,$string);
/***使所有电子邮件成为热链接***/
$string=preg\u replace(“/([\w-?&;\.\/]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}[0-9]{1,3})(\]?)/i“,”,$string);
返回$string;
}

有很多带有URL的边缘案例。比如url可以包含方括号,也可以不包含协议等等,这就是为什么regex是不够的

我创建了一个PHP库,可以处理很多边缘情况:

您可以从字符串中提取URL或直接突出显示它们。
例如:


更聪明,但仍不完美。忽略ssh+svn之类的内容。您可能还希望排除
Good,但如果查看表达式,它只允许空格和
。我相信这消除了任何HTML注入。Bron:不,您使用匹配的值不仅作为属性值,而且还作为元素文本内容。这正是我想要的!感谢那些希望所有子模式转换为非捕获的子模式,而前斜线逃逸的人。感谢那些希望所有子模式转换为非捕获的子模式,而前斜线逃逸的人。感谢那些希望所有子模式转换为非捕获的子模式,以及希望所有子模式转换为非捕获的前斜线逃逸的人。感谢谢谢。感谢任何希望所有希望所有子模式转换为非捕获的子模式的人,希望所有子模式转换为非捕获的子模式的人,前斜线逃逃的人的人:以下以下任何人::以下以下以下以下任何人::::以下以下任何人:b::::::::以下以下任何人:(b(?:::((((::::::::::::::(((((((((:::::::::::::::::::[a-a-a-a-a-z[a-z[a-z[a-z[a-z[a-z+))*)|[^\s`!()[]{};:“,«»””))TLD可能有4个以上的字符,请参见:我们如何在preg中使用这个正则表达式?我的意思是,因为它有
代码不能正常工作,例如:
preg\u match(“(?\b…)”),$str)
-所有代码似乎都有注释。无法工作。Preg_match&Preg_match_每次都失败,即使删除了单引号/双引号。为什么要将tld限制为3个字符?看看: