我有大量用户提交的内容。它是HTML,可能包含URL。其中一些已经<a>
已经(如果用户不错),但有时用户很懒,只需输入www.something.com或最好http://www.something.com。
我找不到一个像样的正则表达式来捕获URL但忽略紧靠双引号或'&gt;'右边的那些。有人有吗?
答案 0 :(得分:15)
\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]
为了忽略“or”之后发生的匹配,您可以将(?<![">])
添加到正则表达式的开头,这样就可以了
(?<![">])\b(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&@#/%=~_|$?!:,.]*[A-Z0-9+&@#/%=~_|$]
这将匹配完整地址(http://..。)和以www开头的地址。或者ftp。 - 你运气不好像ars.userfriendly.org ......
答案 1 :(得分:11)
这个线程像山丘一样古老,但我在处理自己的问题时遇到了它:也就是说,将任何网址转换为链接,但保留已经在锚标记内的任何网页。过了一会儿,这就是弹出的东西:
(?!(?!.*?<a)[^<]*<\/a>)(?:(?:https?|ftp|file)://|www\.|ftp\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]
使用以下输入:
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>
这是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>
只是想回馈一下来拯救某人。
答案 2 :(得分:10)
我对原始答案中包含的正则表达式做了一些修改:
(?<![.*">])\b(?:(?:https?|ftp|file)://|[a-z]\.)[-A-Z0-9+&#/%=~_|$?!:,.]*[A-Z0-9+&#/%=~_|$]
允许更多子域,并且还对标签运行更全面的检查。要将此应用于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 );
注意,我从正则表达式中删除了@,以便将其用作preg_replace的分隔符。无论如何,@很少会在URL中使用。
显然,你可以修改替换文本,删除target =“_ blank”,或者添加rel =“nofollow”等。
希望有所帮助。
答案 3 :(得分:1)
if (preg_match('/\b(?<!=")(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|](?!.*".*>)(?!.*<\/a>)/i', $subject)) {
# Successful match
} else {
# Match attempt failed
}
答案 4 :(得分:0)
无耻的插件:你可以在这里(regular expression replace a word by a link)寻找灵感。
问题是要用某个链接替换某个单词,除非已经有链接。所以你遇到的问题或多或少都是一样的。
您需要的是一个匹配URL(代替单词)的正则表达式。最简单的假设是:URL(可选)以"http://"
,"ftp://"
或"mailto:"
开头,只要没有空格字符,换行符,标记括号,就会持续或引号)。
当心,前面有很长的正则表达。不区分大小写。
(href\s*=\s*['"]?)?((?:http://|ftp://|mailto:)?[^.,<>"'\s\r\n\t]+(?:\.(?![.<>"'\s\r\n])[^.,!<>"'\s\r\n\t]+)+)
请注意 - 这也会匹配技术无效的网址,并且会将thing.formatted.like.this识别为URL。如果它太不敏感,这取决于您的数据。如果您有返回误报的示例,我可以对正则表达式进行微调。
正则表达式将产生两个匹配组。第2组将包含匹配的东西,很可能是URL。第1组将包含空字符串或'href="'
。您可以将其用作此匹配发生在内现有链接的href参数的指示器,而您不必触摸该匹配。
一旦你确认这对你来说是正确的大部分时间(使用用户提供的数据,你永远无法确定),你可以分两步完成其余的工作,正如我提出的那样它在另一个问题:
<a>
标记已有链接。<a>
标记,删除最里面的标记答案 5 :(得分:0)
要跳过现有的只需使用后视 - 将(?<!href=")
添加到正则表达式的开头,所以它看起来像这样:
/(?<!href=")http://\S*/
显然,这不是查找所有类型网址的完整解决方案,但这可以解决您弄乱现有网址的问题。