java - Java 中完美的 URL 验证正则表达式

标签 java regex url

我找到了那个页面:https://mathiasbynens.be/demo/url-regex其中很好地列出了用于 URL 验证的不同正则表达式及其可能性。 Diego Perini 的正则表达式是最强大的,我想在 Java 中使用它。但是,如果我那样使用它,它就不起作用:

public class URLValidation {
    // "\" replaced by "\\"
    private static Pattern REGEX = Pattern.compile("_^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}0-9]+-?)*[a-z\\x{00a1}-\\x{ffff}0-9]+)*(?:\\.(?:[a-z\\x{00a1}-\\x{ffff}]{2,})))(?::\\d{2,5})?(?:/[^\\s]*)?$_iuS");

    private static String[] URLs = new String[] { "http://foo.com/blah_blah", "http://foo.com/blah_blah/", "http://foo.com/blah_blah_(wikipedia)", "http://foo.bar?q=Spaces should be encoded" };

    public static void main(String[] args) throws Exception {
        for (String url : URLs) {
            Matcher matcher = REGEX.matcher(url);
            if (matcher.find()) {
                System.out.println(matcher.group());
            }}}}

此代码不输出任何内容,但它应该输出数组中的前三个 URL。如何正确编译正则表达式以使代码正常工作?

更新:感谢您的建议。我在实际应用程序中测试了您的正则表达式。我在那里所做的是遍历日志文件并在每一行中查找 URL。日志文件的时间戳和用户名分别包含在 [] 和 <> 中,有时可以包含特殊的不可见字符,负责格式化(颜色、粗体等),如 \u0003。正则表达式似乎对这种类型的字符串有问题:http://ideone.com/WEcgBY

upd2:如果包含多个 URL,正则表达式如何查找一行中的所有 URL?例如像这样使用它:

String[] urlsFromLine = REGEX.split(line);
for (String url : urlsFromLine) {
    System.out.println(url);
}

最佳答案

使用这个版本:

"(?i)^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?$"

您不必加倍斜杠、添加正则表达式定界符、在模式末尾修饰符,以及将 \u 转换为 \x 表示法。

参见 IDEONE demo :

String[] URLs = new String[] { "http://foo.com/blah_blah", "http://foo.com/blah_blah/", "http://foo.com/blah_blah_(wikipedia)", "http://foo.bar?q=Spaces should be encoded" };
Pattern REGEX = Pattern.compile("(?i)^(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?$");
for (String url : URLs) {
    Matcher matcher = REGEX.matcher(url);
    if (matcher.find()) {
       System.out.println(matcher.group());
    }
}

输出:

http://foo.com/blah_blah
http://foo.com/blah_blah/
http://foo.com/blah_blah_(wikipedia)

更新

要匹配较大文本中的 URL,需要将 ^$ 替换为 \\b:

Pattern REGEX = Pattern.compile("(?i)\\b(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?!(?:10|127)(?:\\.\\d{1,3}){3})(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))\\.?)(?::\\d{2,5})?(?:[/?#]\\S*)?\\b");

参见 another demo

关于java - Java 中完美的 URL 验证正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31440758/

相关文章:

python - 从列表中搜索并替换字符串中的字符

python Regex-根据条件获取匹配

url - 捕获 Rust 中的错误(Rust URL)

java - SimpleCursorAdapter 未定义?

java - 从字符串中删除所有不在白名单上的字符

javascript - 更改滚动时的 URL 哈希值并保持后退按钮正常工作

java - 在 Java Spring 框架中链接到 Facebook 等外部网站

java - 在windows中监听 "folder opening"事件(java)

java - Grails 错误 - 执行 Bootstrap 时出错 : java. lang.ClassNotFoundException: DefaultQuartzConfig

java - 如何在 jfreechart 中将形状与动态图表集成