使用以下代码将邮件中的网址转换为HTML链接:
$message = preg_replace("#(http|https|ftp|ftps)://([.]?[&;%=a-zA-Z0-9_/?-])*#",
"<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);
$message = preg_replace("#(^| |\n)(www([.]?[&;%=a-zA-Z0-9_/?-])*)#",
"\\1<a href=\"away?to=http://\\2\" target=\"_blank\">\\2</a>", $message);
除了下列情况外,它几乎适用于所有链接:
1) http://example.com/mediathek#/video/1976914/zoom:-World-Wide
此处的问题是链接中的#
和:
,因为不会转换完整的链接。
2) If someone just writes "www" in a message
示例:<a href="http://www">www</a>
所以问题是在上面的代码中是否有任何方法可以修复这两种情况?
答案 0 :(得分:2)
由于您希望将哈希(#
)包含在正则表达式中,因此您需要将分隔符更改为正则表达式中未包含的字符,例如!
。所以,你的正则表达式应该是这样的:
$message = preg_replace("!(http|https|ftp|ftps)://([.]?[&;%#:=a-zA-Z0-9_/?-])*!",
"<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);
这有帮助吗?
但是,如果您希望更多地遵循规范(RCF 1738),则可能希望排除URL中不允许的%
。还有一些你不包括的允许的字符:
如果您要包含这些字符,则应使用%
对正则表达式进行分隔。
答案 1 :(得分:1)
夫妻小调整。将\#
和:
添加到第一个正则表达式,然后将*
更改为第二个正则表达式中的+
:
$message = preg_replace("#(http|https|ftp|ftps)://([.]?[&;%=a-zA-Z0-9_/?\#:-])*#",
"<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);
$message = preg_replace("#(^| |\n)(www([.]?[&;%=a-zA-Z0-9_/?-])+)#",
"\\1<a href=\"away?to=http://\\2\" target=\"_blank\">\\2</a>", $message);
答案 2 :(得分:1)
在我看来,解决这个问题是徒劳的。一个很好的选择是通过regex (从协议开始:http,ftp,mail ...或www)找到可能是URL的URL,然后使用FILTER_VALIDATE_URL进行测试。请记住,这个过滤器不是防水方式,因为PHP手册说:
"Note that the function will only find ASCII URLs to be valid; internationalized domain names (containing non-ASCII characters) will fail."
代码示例(未测试):
$message = preg_replace_callback(
'~(?(DEFINE)
(?<prot> (?>ht|f) tps?+ :// ) # you can add protocols here
)
(?>
<a\b (?> [^<]++ | < (?!/a>) )++ </a> # avoid links inside "a" tags
|
<[^>]++> # and tags attributes.
) (*SKIP)(?!) # makes fail the subpattern.
| # OR
\b(?>(\g<prot>)|www\.)(\S++) # something that begins with
# "http://" or "www."
~xi',
function ($match) {
if (filter_var($match[2], FILTER_VALIDATE_URL)) {
$url = (empty($match[1])) ? 'http://' : '';
$url .= $match[0];
return '<a href="away?to=' . $url . '"target="_blank">'
. $url . '</a>';
} else { return $match[0] }
},
$message);