需要一个好的正则表达式将URL转换为链接,但只留下现有的链接

Nic*_*ing 20 html php regex url

我有大量用户提交的内容.它是HTML,可能包含URL.其中一些<a>已经是(如果用户是好的)但有时用户是懒惰的,只需输入www.something.com或最好是http://www.something.com.

我找不到一个像样的正则表达式来捕获URL但忽略那些紧靠双引号或'>'的权利.谁有一个?

Tim*_*ker 16

RegexBuddy的创建者Jan Goyvaerts 已经回复了Jeff Atwood的博客,该博客解决了Jeff所遇到的问题并提供了一个很好的解决方案.

\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]
Run Code Online (Sandbox Code Playgroud)

为了忽略"或"旁边发生的匹配,你可以添加(?<![">])到正则表达式的开头,所以你得到

(?<![">])\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]
Run Code Online (Sandbox Code Playgroud)

这将匹配完整的地址(http:// ..)和以www开头的地址.或者ftp. - 你运气不好像ars.userfriendly.org这样的地址......


小智 12

这个线程像山丘一样古老,但我在处理我自己的问题时遇到了它:也就是说,将任何网址转换为链接,但保留已经在锚标记内的任何网页.过了一会儿,这就是弹出的东西:

(?!(?!.*?<a)[^<]*<\/a>)(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]
Run Code Online (Sandbox Code Playgroud)

通过以下输入:

http://www.google.com
http://google.com
www.google.com

<p>http://www.google.com<p>

this is a normal sentence. let's hope it's ok.

<a href="http://www.google.com">www.google.com</a>
Run Code Online (Sandbox Code Playgroud)

这是preg_replace的输出:

<a href="http://www.google.com" rel="nofollow">http://www.google.com</a>
<a href="http://google.com" rel="nofollow">http://google.com</a>
<a href="www.google.com" rel="nofollow">www.google.com</a>

<p><a href="http://www.google.com" rel="nofollow">http://www.google.com</a><p>

this is a normal sentence. let's hope it's ok.

<a href="http://www.google.com">www.google.com</a>
Run Code Online (Sandbox Code Playgroud)

只是想贡献一些时间来拯救某人.

  • 这对我有用.你是冠军!添加了'i'标志,这就是结果php:`$ text = preg_replace('@(?!(?!.*?<a)[^ <]*<\/a>)(?:(?: HTTPS | FTP |文件)?[?!-A-Z0-9 +&#/%=〜_ | $:,] // | | WWW\FTP \)*[A-Z0-9 + &#/%= ~_ | $] @ i','<a href="\0" target="_blank">\0 </a>',$ text);`上面的其他解决方案不起作用我在每一个案例中. (6认同)

小智 10

我对原始答案中包含的正则表达式做了一些修改:

(?<![.*">])\b(?:(?:https?|ftp|file)://|[a-z]\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]
Run Code Online (Sandbox Code Playgroud)

它允许更多子域,并且还可以对标签进行更全面的检查.要将此应用于PHP的preg替换,您可以使用:

$convertedText = preg_replace( '@(?<![.*">])\b(?:(?:https?|ftp|file)://|[a-z]\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]@i', '<a href="\0" target="_blank">\0</a>', $originalText );
Run Code Online (Sandbox Code Playgroud)

注意,我从正则表达式中删除了@,以便将其用作preg_replace的分隔符.无论如何,@很少会在URL中使用.

显然,你可以修改替换文本,删除target ="_ blank",或者添加rel ="nofollow"等.

希望有所帮助.