完全合格的域名验证

Ria*_*aan 20 regex bash fqdn

是否有快速而肮脏的方法来验证是否输入了正确的FQDN?请记住,没有DNS服务器或Internet连接,因此必须通过regex/awk/sed进行验证.

有任何想法吗?

bkr*_*bkr 40

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)
Run Code Online (Sandbox Code Playgroud)

对于像这样的事情,正则表达式总是充其量近似,规则会随着时间的推移而变化.上面的正则表达式是在考虑以下内容时编写的,并且特定于主机名 -

主机名由一系列与点连接的标签组成.每个标签长度为1到63个字符,可能包含:

  • ASCII字母az(以不区分大小写的方式),
  • 数字0-9,
  • 和连字符(' - ').

另外:

一些假设:

  • TLD至少为2个字符且仅为az
  • 我们希望至少比TLD高1级

结果:有效/无效

  • 911.gov - 有效
  • 911 - 无效(无TLD)
  • a-.com - 无效
  • -a.com - 无效
  • a.com - 有效
  • a.66 - 无效
  • my_host.com - 无效(非核心)
  • typical-hostname33.whatever.co.uk - 有效

编辑:John Rix提供了正则表达式的另一种方法,使TLD的规范可选:

(?=^.{1,253}$)(^(((?!-)[a-zA-Z0-9-]{1,63}(?<!-))|((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63})$)
Run Code Online (Sandbox Code Playgroud)
  • 911 - 有效
  • 911.gov - 有效

编辑2:有人要求在js中使用的版本.它在js中不起作用的原因是因为js不支持正则表达式.特别是,代码(?<!-)- 指定前一个字符不能是连字符.

无论如何,在这里它被重写没有外观 - 有点丑陋但不多

(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)
Run Code Online (Sandbox Code Playgroud)

您也可以在John Rix的版本上进行类似的替换.

编辑3:如果你想允许尾随点 - 这在技术上是允许的:

(?=^.{4,253}\.?$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}\.?$)
Run Code Online (Sandbox Code Playgroud)

我不熟悉尾随点语法,直到@ChaimKut指出它们,我做了一些研究

然而,使用尾随点似乎会在我玩的各种工具中产生一些不可预测的结果,因此我建议谨慎一些.


Joh*_*gle 13

现在更难了,拥有国际化的域名和数千个(!)新TLD.

简单的部分是你仍然可以在"."上拆分组件.

您需要一个可注册TLD列表.有一个网站:

https://publicsuffix.org/list/effective_tld_names.dat

您只需要检查ICANN认可的那些.请注意,可注册TLD可以包含多个组件,例如"co.uk".

然后是IDN和punycode.域名现在是Unicode.例如,

"xn - nnx388a"相当于"台湾".顺便提一下,这两个都是有效的顶级域名.

有关punycode转换代码,请参阅" http://golang.org/src/pkg/net/http/cookiejar/punycode.go ".

检查每个域组件的语法也有新规则.请参阅http://tools.ietf.org/html/rfc5890上的 RFC5890

组件可以是A标签(仅限ASCII)或Unicode.ASCII标签遵循旧语法,或者以"xn--"开头,在这种情况下,它们是Unicode字符串的punycode版本.

Unicode的规则非常复杂,在RFC5890中给出.这些规则旨在防止从左到右和从右到左集合混合字符.

对不起,没有简单的答案.


小智 7

这个正则表达式是你想要的:

(?=^.{1,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)
Run Code Online (Sandbox Code Playgroud)

它匹配您的示例域(groupa-zone1appserver.example.com或cod.eu等...)

我会试着解释一下:

(?=^.{1,254}$) 匹配长度在1到254个字符之间的域名(可以以任何字符开头),如果我们假设co.uk是最小长度,它也可以是5,254.

(^ 开始比赛

(?: 定义匹配组

(?!\d+\.) 域名不应由数字组成,因此不接受1234.co.uk或abc.123.uk,而1a.ko.uk是.

[a-zA-Z0-9_\-] 域名应由只有a-zA-Z0-9_-的单词组成

{1,63} 任何域级别的长度最多为63个字符,(可能是2,63)

+

(?:[a-zA-Z]{2,})$) 域名的最后部分不应该跟任何其他单词,并且必须由最少2个字符a-zA-Z组成的单词组成

  • `?:(?!\ d + \.)`不应该在那里,因为仅限数字的域仍然有效,如911.com (2认同)