regex - Java中根据RFC 1035标准检查域名

标签 regex domain-name rfc1035

我正在尝试编写代码来检查域名是否根据 rfc 1035 标准有效。 RFC 1035( https://www.rfc-editor.org/rfc/rfc1035 ) 标准对域名有以下标准:

<domain> ::= <subdomain> | " "

<subdomain> ::= <label> | <subdomain> "." <label>

<label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]

<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>

<let-dig-hyp> ::= <let-dig> | "-"

<let-dig> ::= <letter> | <digit>

<letter> ::= any one of the 52 alphabetic characters A through Z in
upper case and a through z in lower case

<digit> ::= any one of the ten digits 0 through 9

Note that while upper and lower case letters are allowed in domain
names, no significance is attached to the case.  That is, two names with
the same spelling but different case are to be treated as if identical.

The labels must follow the rules for ARPANET host names.  They must
start with a letter, end with a letter or digit, and have as interior
characters only letters, digits, and hyphen.  There are also some
restrictions on the length.  Labels must be 63 characters or less.

我用 Java 编写了以下代码片段来检查域名是否根据 rfc 1035 有效。

//DomainUtils.java
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class DomainUtils {

   private static Pattern pDomainNameOnly1;
   private static Pattern pDomainNameOnly2;

   private static final String DOMAIN_NAME_PATTERN_CHK_1 = "^(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";
   private static final String DOMAIN_NAME_PATTERN_CHK_2 = "^((?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)\\.)+(?![0-9-])[A-Za-z0-9-]{1,63}(?<!-)$";

   static {
       pDomainNameOnly1 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_1);
       pDomainNameOnly2 = Pattern.compile(DOMAIN_NAME_PATTERN_CHK_2);
   }

   public static boolean isValidDomainName(String domainName) {
       return (pDomainNameOnly1.matcher(domainName).find() || pDomainNameOnly2.matcher(domainName).find() || domainName.equals(" "));
   }

}

//Main.java
public class Main{
   public static void main(String[] args){
       boolean valid = DomainUtils.isValidDomainName("a123456789a123456789a123456789a123456789a123456789a1234567891234.ARPA"); //check if domain name is valid or not
       System.out.println("Valid domain name : " + valid);
   }

}

我只是想检查是否有一些有效的方法(除了我写的之外)来检查域名是否符合 rfc 1035 标准?另外,如果我需要检查我的代码是否适用于 rfc 1035 标准的极端情况,那么我可以在哪里检查。是否有一些现有的库可以用于此检查?

最佳答案

试试这个:

^[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$

demo所示

为了构造这个表达式,我们首先使用标签组件(集合 a-zA-Z 中的单个字符,后跟(可选)集合 a-zA-Z0-9- 中的一系列字符,并以非 - 结尾(连字符)允许在内部,但不能在标签的开头或结尾)导致

[a-zA-Z]([a-zA-Z0-9-]*[a-zA-Z0-9])?

此表达式在以下模式下重复:

A(\.A)*

这意味着 A 的序列,后跟任意数量(甚至 0)的点序列,后跟 A 的另一个实例.

通过将上述正则表达式替换到 A 的位置,我们得到了最终的正则表达式。 anchor 消除了字符串开头/结尾处的任何其他周围字符串。

要检查标签是否最多为 63 个字符,您可以这样做

[a-zA-Z]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?

但请注意,此正则表达式会编译为一个非常大的表自动机(具有许多状态的自动机),因此如果空间不足,最好放松一下。

关于regex - Java中根据RFC 1035标准检查域名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56835571/

相关文章:

c# - 在大字符串中查找标记

php - 如何在 MYSQL 中使用 REGEXP 来匹配数组中的日期?

regex - 打印文件中pattern1和pattern2之间的数据,而不打印pattern2

javascript - 打印出正则表达式后的最后一个字符

java - 在多个客户域上运行 Google App Engine 应用程序

dns - 如何制作一个脚本,对多个网站执行 nslookup -q=ns 并将结果导出到文件

dns - QD 在 DNS RFC1035 中代表什么

asp.net-mvc - 在 Visual Studio 中将域名从 localhost 更改为自定义名称

python - 如何使用 Python 验证域名是否符合 RFC 1035?