我有一个正则表达式函数,它会接受我输入的$ text并返回相同的文本,但是看起来像远程的任何东西就像格式化为嵌入式<a href></a>
的网址。
preg_replace('@(http)?(s)?(://)?(([-\w]+\.)+([^\s]+)+[^,.\s])@', '<a href="http$2://$4">$1$2$3$4</a>', $text)
示例输出:
http://www.example.com
=&gt; <a href="http://www.example.com">http://www.example.com</a>
https://www.example.com
=&gt; <a href="https://www.example.com">https://www.example.com</a>
www.example.com
=&gt; <a href="http://www.example.com">www.example.com</a>
现在,我想扩展它,以便不执行此操作时,遇到一个“在它前面的网络地址 - 我正试图阻止它从重新嵌入已经在href =“”属性中的地址。所以,我尝试添加负面回顾,如下所示:
preg_replace('@(?<!")(http)?(s)?(://)?(([-\w]+\.)+([^\s]+)+[^,.\s])@', '<a href="http$2://$4">$1$2$3$4</a>', $text)
不幸的是,添加回顾不仅不会阻止引擎替换双引号前面的地址上的模式,它最终也会完全破坏输出。我无法弄清楚它是不是?操作员弄乱了回顾,或者回顾周围的括号实际上是否在替换规则中抛弃了我的反馈。再一次 - 我思考他们没有贡献任何捕获的模式。
答案 0 :(得分:3)
我建议这个正则表达式不需要任何锚定(因此可以在包含链接和文本的页面上使用):
<a href\s?=\s?"http(s)?://([^"]+)">([^<]+)</a>|(http)?(s)?(://)?((?:[-\w]+\.)+\S+[^,.\s])
用法:
$result = preg_replace('~<a href\s?=\s?"http(s)?://([^"]+)">([^<]+)</a>|(http)?(s)?(://)?((?:[-\w]+\.)+\S+[^,.\s])~', '<a href="http$1$5://$2$7">$3$4$5$6$7</a>', $text);
正则表达式匹配正常&#39; url和已经包含在锚标记之间的URL,但在替换中对它们的处理方式不同。
答案 1 :(得分:0)
使用以下正则表达式在<a>
代码中嵌入网站地址,而不是嵌入已嵌入的网站地址。
正则表达式:
^(?!<a href.*$)(http)?(s)?(:\/\/)?(([-\w]+\.)+([^\s]+)+[^,.\s])
<强>换人:强>
<a href="http$2://$4">$1$2$3$4</a>
PHP代码:
<?php
$mystring = <<<EOT
http://www.example.com
https://www.example.com
www.example.com
<a href="http://www.example.com">http://www.example.com</a>
EOT;
$pattern = "~^(?!<a href.*$)(http)?(s)?(:\/\/)?(([-\w]+\.)+([^\s]+)+[^,.\s])~m";
$replacement = '<a href="http$2://$4">$1$2$3$4</a>';
echo preg_replace($pattern, $replacement, $mystring);
?>
<强>输出:强>
<a href="http://www.example.com">http://www.example.com</a>
<a href="https://www.example.com">https://www.example.com</a>
<a href="http://www.example.com">www.example.com</a>
<a href="http://www.example.com">http://www.example.com</a>
答案 2 :(得分:0)
Avinash Raj和Jerry都提供了与我的问题中所述的参数和要求相匹配的解决方案,并且大大扩展了我对正则表达式的了解。不幸的是,我发现两个解决方案都开始用iframe src
属性,mailto:
地址(@符号后面)等替换字符串中带有句点分隔的地址。
经过多次尝试让正则表达式来弥补所有这些可能性之后,作为Jerry解决方案中第一个替代<a>
标签内的地址的替代方案,我得出结论杰克,他发布了这里的第一个解决方案(并且不再存在)是正确的;我根本无法为我的用户提供协议猜测。所以我改变了要求:协议是必要的,用户必须指定http(s)或ftp(s)。这不是我的要求,但我想不出更好的解决方案。为此,I devised this (considerably simpler) regex and substitution规则如下:
<强>正则表达式:强>
~(?<!["'>])(http|ftp)(s)?://((?:[-\w]+\.)+\S+[^,.\s])~g
<强>换人:强>
<a href="$1$2://$3">$3</a>
我将此作为一个单独的答案发布,因为从技术上来说,它不会受到Avinash和Jerry所维护的参数的影响,而且这些参数构成了我的问题。问题的简单事实是,我无法找到一个解决方案,它会破坏iframe和其他我无法控制的元素。但我不能想到比要求用户为其链接包含协议更好的方法。我认为这是最合理的妥协,但如果有人有更好的解决方案,我很乐意听到它。
感谢大家对正则表达式本质的深入了解,特别感谢Avinash再次向我展示了regex101。