java - 如何在 Java 中验证允许通配符 (*, %) 的 URL(域)

标签 java regex url-validation

我想在 java 中检查允许通配符的验证 URL。

我发现了一些关于在 java 中验证 URL 的很好的例子(REGEXurlValidator),但是那些没有提供通配符。

这是我正在练习的:

代码(urlValidator)

public void urlValidiTest(){
    System.out.println(this.urlCheck("https://www.google.com"));
    System.out.println(this.urlCheck("https://google.com"));
    System.out.println(this.urlCheck("*.com"));
}

public boolean urlCheck(String url){
    return new UrlValidator().isValid(url);
}

输出

true

true

false

代码(正则表达式)

public void regexTest() {
  String[] URLs = new String[] { "http://www.google.com", "http://google.com/","*.com" };
    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://www.google.com

http://google.com/

我想做的是上面所有的 URL 都是有效的。

我应该如何解决这个问题?

如有任何意见,我们将不胜感激。谢谢。

更新

我摆脱了方案部分并在答案之后添加了 |* 和 |\.* 到域部分(|* 和 |.* 给我一个错误 - 无效的转义序列(有效的是\b\t\n\f\r\"\' ) - 但我不确定更改是否正确。

现在它不允许“google.com”;但允许其他人(“www.google.com”、“google.com”、“.google.com”、“.com”)

 public void regexValidator(String str){

    Pattern REGEX = Pattern.compile(""
            + "(?i)^(?:\\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]))|"

            //DOMAIN
            + "(?:(?:[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*)?$");

    Matcher _matcher = REGEX.matcher(str);
    if(_matcher.find()){
        System.out.println("[O] " + str);
    }
    else {
        System.out.println("[X]" + str);
    }
}

public void validate(){
    System.out.println("TEST START");
    this.regexValidator("https://www.google.com");
    this.regexValidator("www.google.com");
    this.regexValidator("google.com");
    this.regexValidator("*.google.com");
    this.regexValidator("*.com");
    System.out.println("DONE");
}

TEST START

[X] https://www.google.com

[O] www.google.com

[O] google.com

[O] *.google.com

[O] *.com

DONE

需要任何帮助。谢谢。

最佳答案

对此持保留态度,我现在无法访问 Java 并且是凭空想到的,所以如果这里有错误,请随时纠正我。

您需要更新正则表达式以包含通配符。考虑到事情的复杂性,这并非微不足道。

让我们首先分解您的正则表达式:

(?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*
    )?
$

我们现在可以看到方案、用户名/密码对(带有 @ 字符的组)、域本身的大组以及端口和端口组一个用于可能的路径、查询或片段部分。大组可以分为两部分(由 | (OR) 分隔),第一部分用于 IP 地址,具有否定前瞻性以禁止本地 IP,后者用于命名域,由一个或多个部分组成,中间用点分隔,最后是 TLD。

那么你需要做什么来允许通配符?在你想要的每个组中添加一个通配符(*%)允许被通配符替换:

如果您想为方案允许使用通配符,请在此处添加一个:

    (?:
        (?:
            https?|ftp
            |\*    <-----
        )
        ://
    )

如果你想允许用户名和/或密码部分使用通配符,你不需要做任何事情,你的正则表达式已经允许任何非空白字符,所以*: *@*@ 已经有效。

如果要允许域名使用通配符,请在此处添加:

        (?:
            (?:
                [a-z\u00a1-\uffff0-9]-*
            )*
            [a-z\u00a1-\uffff0-9]+
            |\*    <-----
        )
        (?:
            \.
            (?:
                [a-z\u00a1-\uffff0-9]-*
            )*
            [a-z\u00a1-\uffff0-9]+
            |\.\*    <-----
        )*

如果您想为 TLD 允许使用通配符,请在此处添加一个:

        (?:
            \.
            (?:
                [a-z\u00a1-\uffff]{2,}
                |\*    <-----
            )
        )

如果您想为端口允许通配符,请在此处添加一个:

    (?:
        :\d{2,5}
        |:\*    <-----
    )?

如果你想允许路径的通配符,你不需要做任何事情,你的正则表达式(/*/*/*/foobar 等已经有效)。

最后但并非最不重要的一点是,如果您想同时允许方案和域名使用通配符(如您的示例),您需要添加一个新组并将其放入: p>

    |
    (?:
        \*
        \.
        (?:
            [a-z\u00a1-\uffff]{2,}
        )
    )
    (?:
        :\d{2,5}
    )?
    (?:
        [/?#]\S*
    )?

基本上只需将其添加到最后一组之后和 $ 符号之前。如果需要,请不要忘记在 TLD 和/或端口中添加通配符。

关于java - 如何在 Java 中验证允许通配符 (*, %) 的 URL(域),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50447988/

相关文章:

iphone - 准确验证 URL

java - AccountManager 帐户选择器 Intent

javascript - 在字符串中转义 RegExp.lastMatch ($&)

图形元素上的 Java MouseListener

php - 下载youtube文件时将eregi转换为正则表达式

javascript - 正则表达式以验证特殊字符集

ruby-on-rails - (rails) 使用正则表达式验证 URL 帮助

string - Dart/Flutter - 验证 URL 的字符串

java - Ubuntu 上 Eclipse Java ADT 的菜单栏问题

Java初学者问题-向屏幕添加多个项目