检查有效链接(URL)

19

我正在阅读这个其他问题,其中有一些非常好的正则表达式,但据我所见,它们中没有任何一个可以与BASH命令一起使用,因为BASH命令不支持如此复杂的正则表达式。

if echo "http://www.google.com/test/link.php" | grep -q '(https?|ftp|file)://[-A-Z0-9\+&@#/%?=~_|!:,.;]*[-A-Z0-9\+&@#/%=~_|]'; then 
    echo "Link valid"
else
    echo "Link not valid"
fi

但是这并不起作用,因为grep -q不能正常工作...

编辑,好的,我刚刚意识到grep有一个“扩展正则表达式”(-E)选项,看起来它可以正常工作。但如果有更好/更快的方法,我仍然很想了解。


你可能需要审视一下提出这个问题的动机。 程序员试图对URL / URI和电子邮件地址进行静态评估,这可以显示出它们在语法上是有效的,但无法告诉您其可访问性。 例如,http://www.example.com/bogus#fragment将始终在语法上是有效的,并且(据推测)将始终返回404错误。 - msw
这个函数不需要知道链接是否有效,只需要知道它是一个链接。 - Mint
一个永远无法定位资源的URL有什么用处?为什么还要费心检查呢? - msw
如果您想评估某个输入是否需要进行检查,因为它看起来像是一个URL。 - rubo77
3个回答

34

以下内容适用于 Bash 版本大于等于 3.2,而且不使用 grep

regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]*[-[:alnum:]\+&@#/%=~_|]'
string='http://www.google.com/test/link.php'
if [[ $string =~ $regex ]]
then 
    echo "Link valid"
else
    echo "Link not valid"
fi

我使用了[:alnum:]简化了你的正则表达式,它也匹配任何字母数字字符(例如,Э或ß),但是其支持情况取决于底层的正则表达式库。这是另一种潜在的简化方法,它使用+而不是*和重复序列(尽管你的第二个序列与第一个不同)。

regex='(https?|ftp|file)://[-[:alnum:]\+&@#/%?=~_|!:,.;]+'

4
http://печки-лавочки.рф/ 存在一个 bug,但它是一个有效的网址。更完整的正则表达式可以在 https://dev59.com/NHVC5IYBdhLWcg3w21Iq 找到。 - Nicolas Raoul
1
这很有帮助。但我认为你想要锚定正则表达式,以避免像 'garbage http://google.com' 这样的字符串被视为有效。我只是在正则表达式的开头和结尾添加了 ^ 和 $,如下所示: regex='^(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]$' - Christopher Werby
1
@rubo77:那会产生许多误报。一些,但不是全部,这些和许多荒谬的字符串。它缺乏特定性,可能匹配人们想要有意排除的URL方案。一个更好的短正则表达式是使用我的直到两个斜杠:^(https?|ftp|file)://,只比你的略长。这可以很容易地修改以包括或排除任何方案。因此,它具有高可维护性。 - Dennis Williamson
1
答案不包括(允许的)特殊字符,如德语中的ä等。 - rubo77
2
@rubo77:我只是复制了原帖中的正则表达式。我已经编辑了我的答案,现在它支持更大的字符集。 - Dennis Williamson
显示剩余2条评论

5

由于我声望不够,无法在上面进行评论,因此我将通过此答案修改Dennis的回答。

我将Christopher的更新内容纳入了正则表达式中,并添加了更多内容,以便URL必须至少具有以下格式:

http://w.w(必须含有句点)。

并稍微调整了输出 :)

regex='^(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]\.[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]$'

url='http://www.google.com/test/link.php'
if [[ $url =~ $regex ]]
then 
    echo "$url IS valid"
else
    echo "$url IS NOT valid"
fi

1

可能是因为正则表达式是用PCRE语法编写的。看看你的系统上是否有(或可以安装)程序pcregrep - 它具有与grep相同的语法,但接受Perl兼容的正则表达式 - 你应该能够使其工作。

另一个选择是尝试grep-P选项,但man页面说这是“高度实验性的”,所以它可能或可能不会真正起作用。

我要说的是,你应该仔细考虑是否真的适合使用这个或任何正则表达式来验证URL。如果你想要正确的验证,你可能最好找到或编写一个小脚本,比如Perl,来使用语言的URL验证功能。

编辑:针对你在问题中的编辑,我没有注意到那个正则表达式也在“扩展”语法中有效。我认为你无法得到比那更好/更快的了。


这只是后端,任何内容显示之前都会在php中进行更多的验证。 - Mint
并非所有的 grep 实现都具有 -P 选项。 - Pryftan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接