35

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

有任何想法吗?

4

6 回答 6

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

正则表达式总是充其量是此类事情的近似值,并且规则会随着时间而变化。上述正则表达式的编写考虑了以下内容,并且特定于主机名-

主机名由一系列用点连接的标签组成。每个标签的长度为 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 - 无效(取消划线)
  • 典型主机名33.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})$)
  • 911 - 有效
  • 911.gov - 有效

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

无论如何,在这里它被重写而没有向后看 - 有点难看但不多

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

您也可以对 John Rix 的版本进行类似的替换。

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

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

在@ChaimKut 指出它们并且我做了一些研究之前,我不熟悉尾随点语法

然而,在我使用的各种工具中,使用尾随点似乎会导致一些不可预测的结果,所以我建议谨慎行事。

于 2013-11-25T22:34:57.930 回答
19

如今,国际化域名和数千个(!)新 TLD 变得更加困难。

简单的部分是您仍然可以在“。”上拆分组件。

您需要一份可注册 TLD 的列表。有一个网站:

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

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

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

“xn--nnx388a”相当于“台湾”。顺便说一句,这两个都是有效的 TLD。

punycode转换代码见“http://golang.org/src/pkg/net/http/cookiejar/punycode.go”。

检查每个域组件的语法也有新的规则。请参阅https://www.rfc-editor.org/rfc/rfc5890上的 RFC5890

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

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

抱歉,没有简单的答案。

于 2014-10-28T21:41:34.653 回答
7

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

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

它匹配您的示例域(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 个 char a-zA-Z 的单词组成

于 2012-08-04T20:30:19.563 回答
4

我们使用这个正则表达式来验证在野外出现的域。它涵盖了我所知道的所有实际用例。欢迎新的。根据我们的指南,它避免了非捕获组和贪婪匹配。

^(?!.*?_.*?)(?!(?:[\w]+?\.)?\-[\w\.\-]*?)(?![\w]+?\-\.(?:[\w\.\-]+?))(?=[\w])(?=[\w\.\-]*?\.+[\w\.\-]*?)(?![\w\.\-]{254})(?!(?:\.?[\w\-\.]*?[\w\-]{64,}\.)+?)[\w\.\-]+?(?<![\w\-\.]*?\.[\d]+?)(?<=[\w\-]{2,})(?<![\w\-]{25})$

证明及解释:https ://regex101.com/r/FLA9Bv/40

验证域时有两种方法可供选择。

书本上的 FQDN 匹配(理论定义,实践中很少遇到):

实用/保守的 FQDN 匹配(实用定义,在实践中预期和支持):

  • 与以下例外/补充相匹配的书籍
  • 有效字符:[a-zA-Z0-9.-]
  • 标签不能以连字符开头或结尾(根据RFC-952RFC-1123/2.1
  • TLD 最小长度为 2 个字符,最大长度为 24 个字符,根据当前现有记录
  • 不匹配尾随点

上面的正则表达式包含书本和实用规则。

于 2019-07-21T00:08:27.597 回答
3

考虑#1:

请注意,由于 RFC-2181 中的宽松要求,DNS 标签可以包含几乎任何符号组合(但是,长度限制仍然存在):

"任何二进制字符串都可以用作任何资源记录的标签。DNS 协议的实现不得对可以使用的标签施加任何限制。特别是,DNS 服务器不得拒绝为区域提供服务,因为它包含标签某些 DNS 客户端程序可能无法接受。 ”(https://www.rfc-editor.org/rfc/rfc2181#section-11

考虑#2:

“还有一条附加规则,本质上要求顶级域名不能是全数字的”https://www.rfc-editor.org/rfc/rfc3696#section-2

考虑到这两个因素,正确的正则表达式如下所示:

/^(?!:\/\/)(?=.{1,255}$)((.{1,63}\.){1,127}(?![0-9]*$)[a-z0-9-]+\.?)$/i

见演示@http ://regexr.com/3g5j0

于 2017-06-14T01:56:40.467 回答
0

下面的表达式

(^((?=^.{4,253}$)(((http){0,1}|(http){0,1}|(ftp){0,1}|(ws){0,1})(s{0,1}):\/\/){0,1})((((?!-)[\pL0-9\-]{1,63})(?<!-)(\.)){1,})(((?!-)[a-z0-9\-]{1,63})(?<!-)((\/{0,1}[\pL\pN?=\-]*)+){1})$)

将匹配

https://www.tes1t.com/lets/to?878932572
https://www.test.co.uk/lets/to?878932572
http://www.test.com/lets/to?878932572
http://www.test.co.uk/lets/to?878932572
ftp://www.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.test.com/lets/to?878932572
subdomain.subdomain.test.net/lets/to?878932572

sub-domain.test.net/lets/to?878932572
sub-domain.test.net/lets-go/to?878932572
www.test.net/lets/to?878932572
www.test-test.com/
www.test-test.com

subdomain.subdomainsubdomainsuèdomainsubdomainsubdomainsubdomainsubdomain.net/let2s/to?=878932572

www.test-test.co.uk
http://www.test-test-.com/test
www.test-teèst.co.uk/lets
www.test-test.co.uk/lets/
www.test-test.co.uk/lets/to?
test-test.co.uk/lets/to?
test-test.co.uk/lets/
test-test.co.uk/lets
test-test.co.uk
http://test.com/lets/to?878932572
https://test.com/lets/to?878932572
ftp://test.com/lets/to?878932572
ftps://test.com/lets/to?878932572
ws://test.com/lets/to?878932572aa
wss://test.com/lets/to?=878932572bar
test.com

subdomain.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257

但不匹配:

www.-test-fail-.com
www.-test-fail.com
-test-fail.com
test-fail-.com

subdomain.subdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomainubdomainsubdomainsubdomain.test.net/lets/to?878932572

subdomain.subdomainsubdomainsubdcnvcnvcnofhfhghgfhvnhj-mainsubdomainsubdohhghghghfhgffgjh-gfhfdhfdghmainsubdocgvhngvnbnbmghghghaihgfjgfnfhfdghgsufghgghghhdfjgffsgfbdomainsubdomainsubdomainsubdomainsubdomainsubdomainsubdomain.test.net/lets/to?878932572

subdomain.test.test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test..test.khbdomainsubdomainsubdomain.test.net/lets/to?87893257
于 2018-03-16T16:52:04.470 回答