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

发布于 2024-09-06 22:24:23 字数 61 浏览 3 评论 0原文

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

Does anyone have a good (preferably tested) regex for accepting only a valid DNS hostname, IPv4, or IPv6 address?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

大姐,你呐 2024-09-13 22:24:24

我了解您可能被迫使用正则表达式。但是,如果可能的话,最好避免使用正则表达式来执行此任务,而是使用 Java 库类来进行验证。

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

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

I understand that you may be forced to 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.

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 InetAddress instance that contains both the DNS name (if provided) and the IPv4 or IPv6 address.

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

日暮斜阳 2024-09-13 22:24:24

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

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!

ゃ懵逼小萝莉 2024-09-13 22:24:24

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

示例代码:

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());
    }
}

输出:

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

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 library which can parse host names, IPv4 and IPv6 addresses, without triggering DNS lookup. Disclaimer: I am the project manager of that library.

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
〆一缕阳光ご 2024-09-13 22:24:24

受到我在这篇文章,我创建了以下验证器方法,它似乎非常适合简单的验证需求。通过阅读 URI 的 JavaDoc,我删除了一些误报,例如“host: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;
    }
}

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.

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;
    }
}
ヅ她的身影、若隐若现 2024-09-13 22:24:24

你也可以这样做。比方说:

public boolean isHostnameValid(String hostname) {
    try {
        InetAddress.getAllByName(hostname); // throws an error when the hostnme could not be found, if so, then return false
        return true;
    } catch(Exception exc) {
        return false;
    }
}

You can also do this. Let's say:

public boolean isHostnameValid(String hostname) {
    try {
        InetAddress.getAllByName(hostname); // throws an error when the hostnme could not be found, if so, then return false
        return true;
    } catch(Exception exc) {
        return false;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文