用于接受有效主机名、IPv4 或 IPv6 地址的 Java 正则表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3114595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:25:56  来源:igfitidea点击:

Java regex for accepting a valid hostname,IPv4, or IPv6 address

javaregexipv6hostnameipv4

提问by ljbade

Anyone have a good (preferably tested) regex for accpeting only a valid DNS hostname, IPv4 or IPv6 address?

任何人都有一个好的(最好是经过测试的)正则表达式来仅接受有效的 DNS 主机名、IPv4 或 IPv6 地址?

回答by Stephen C

I understand that you may be forcedto use a regex. However, if possible it is better to avoid using regexes for this task and use a Java library class to do the validation instead.

我知道您可能被迫使用正则表达式。但是,如果可能,最好避免在此任务中使用正则表达式,而是使用 Java 库类来进行验证。

If you want to do validation and DNS lookup together, then InetAddress.getByName(String)is a good choice. This will cope with DNS, IPv4 and IPv6 in one go, and it returns you a neatly wrapped InetAddressinstance that contains both the DNS name (if provided) and the IPv4 or IPv6 address.

如果你想一起做验证和DNS查找,那么InetAddress.getByName(String)是一个不错的选择。这将一次性处理 DNS、IPv4 和 IPv6,并返回一个整齐包装的InetAddress实例,其中包含 DNS 名称(如果提供)和 IPv4 或 IPv6 地址。

If you just want to do a syntactic validation, then Apache commons has a couple of classes that should do the job: DomainValidatorand InetAddressValidator.

如果您只想进行语法验证,那么 Apache commons 有几个类可以完成这项工作:DomainValidatorInetAddressValidator.

回答by Kevin Bourrillion

Guava has a new class HostSpecifier. It will even validate that the host name (if it is a host name) ends in a valid "public suffix" (e.g., ".com", ".co.uk", etc.), based on the latest mozilla public suffix list. That's something you would NOT want to attempt with a hand-crafted regex!

Guava 有一个新类HostSpecifier。它甚至会根据最新的 mozilla 公共后缀验证主机名(如果是主机名)是否以有效的“公共后缀”(例如,“.com”、“.co.uk”等)结尾列表。这是您不想使用手工制作的正则表达式尝试的事情!

回答by Sean F

As others have said, doing this with a regex is quite a challenge and not advisable. But it is easy to do with the IPAddress Java librarywhich can parse host names, IPv4 and IPv6 addresses, without triggering DNS lookup. Disclaimer: I am the project manager of that library.

正如其他人所说,使用正则表达式执行此操作是一项相当大的挑战,不可取。但是使用IPAddress Java 库很容易做到,它可以解析主机名、IPv4 和 IPv6 地址,而不会触发 DNS 查找。免责声明:我是那个图书馆的项目经理。

Sample code:

示例代码:

check("1.2.3.4");
check("::1");
check("a.b.com");

static void check(String hostStr) {
    HostName host = new HostName(hostStr);
    try {
        host.validate(); // triggers exception for invalid
        if(host.isAddress()) {
            IPAddress address = host.asAddress();
            System.out.println(address.getIPVersion() + " address: " + address);
        } else {
            System.out.println("host name: " + host);
        }
    } catch(HostNameException e) {
        System.out.println(e.getMessage());
    }
}

Output:

输出:

IPv4 address: 1.2.3.4
IPv6 address: ::1
host name: a.b.com

回答by Henno Vermeulen

Inspired by the code I found in this post, I created the following validator method that seems to suit simple validation needs quite nicely. By reading the JavaDoc of URI I removed some false positives such as "host:80" and "hostname/page", but I cannot guarantee there are some false positives left.

受我在这篇文章中找到的代码的启发,我创建了以下验证器方法,它似乎非常适合简单的验证需求。通过阅读 URI 的 JavaDoc,我删除了一些误报,例如“主机:80”和“主机名/页面”,但我不能保证还有一些误报。

public static boolean isValidHostNameSyntax(String candidateHost) {
    if (candidateHost.contains("/")) {
        return false;
    }
    try {
        // WORKAROUND: add any scheme and port to make the resulting URI valid
        return new URI("my://userinfo@" + candidateHost + ":80").getHost() != null;
    } catch (URISyntaxException e) {
        return false;
    }
}