我正在使用PHP函数自动将文本字符串中的URL转换为人们可以单击的实际链接。它似乎在大多数情况下都有效,但是我发现有些情况下它不起作用。
我根本不理解正则表达式,所以我希望有人可以帮助我解决这个问题。
这是我目前使用的模式:
$pattern = "/(((http[s]?:'/'/)|(www'.))(([a-z][-a-z0-9]+'.)?[a-z][-a-z0-9]+'.[a-z]+('.[a-z]{2,2})?)'/?[a-z0-9.,_'/~#&=;%+?-]+[a-z0-9'/#=?]{1,1})/is";
但是,这里有一些链接,我发现这种模式不匹配:
- www.oakvilletransit.ca - 不确定,但假设由于两个字母的国家/地区代码而 不匹配
- www.grt.ca - 另一个具有 .ca 域但不起作用的人
- 其他几个 .ca 地址
- freepublictransports.com - 没有 www. 或前面有 http://的地址。我希望这些也能工作。
- www.222tips.com - 假设由于地址开头的数字而不匹配。
有谁知道我如何修改该正则表达式模式以匹配这些情况?
编辑 - 它还应该匹配末尾可能有句点的 URL。如果URL是句子的最后一部分,则末尾可能有一个句点不应包含在实际链接中。目前,此模式也考虑到了这一点。
编辑 2 - 我正在使用这样的模式:
$pattern = "/((http|https):'/'/)?([a-z0-9-]+'.)?[a-z][a-z0-9-]+('.[a-z]{2,6}){1,3}('/[a-z0-9.,_'/~#&=;%+?-]*)?/is";
$string = preg_replace($pattern, " <a target='_blank' href='$1'>$1</a>", $string);
// fix URLs without protocols
$string = preg_replace("/href='www/", "href='http://www", $string);
return $string;
以下正则表达式将匹配 URL:
- (可选)带
http://
或https://
( - 可选)带有子域(
www.example.com
、help.example.com
等) - 具有 1-3 个域扩展名,每个扩展名必须是 2-6 个字符(
www.example.com.gu
、www.example.com.au.museum
等) - (可选)末尾使用正斜杠
- (可选)正斜杠后使用有效字符
末尾的/i
使其不区分大小写。
/((http|https):'/'/)?([a-z0-9-]+'.)?[a-z0-9-]+('.[a-z]{2,6}){1,3}('/[a-z0-9.,_'/~#&=;%+?-]*)?/is
编辑:这不会匹配末尾的任何"挂起"句点(例如句子的结尾),因为它不是网址的一部分,不应包含在链接的href
属性中。
编辑2:在您的第一个preg_replace()
中,将$1
更改为$0
。这将插入整个匹配的字符串,而不是其中的单个部分。
编辑 3:(更新 2)以下是在开始时检查http://
或https://
的更好方法:
preg_replace("/href='[^h][^t][^t][^p][^s]?[^:]/", "/href='http:'/'/", $string);
我对上面的所有示例都有问题。
这是一个有效的:
function autolink($string){
$string= preg_replace("#http://(['S]+?)#Uis", '<a href="http://''1">''1</a>', $string);
return $string;
}