用于验证DNS标签的正则表达式(主机名)

Rwa*_*udi 15 regex forms dns validation expression

我想仅使用regualr表达式来验证主机名.

主机名(或DNS术语中的"标签")传统上由RFC 952和RFC 1123定义,并且可以由以下有效字符组成.

项目清单

  • A到Z; 大写字符
  • a到z; 小写字符
  • 0到9; 数字字符0到9
  • - ; 短跑

规则说:

  • 主机名(标签)可以以字母或数字开头或结尾
  • 主机名(标签)不得以' - '开头或结尾(短划线)
  • 主机名(标签)不得包含所有数值
  • 主机名(标签)最多可以包含63个字符

你会如何编写正则表达式来验证主机名?

Mar*_*ers 16

^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$
Run Code Online (Sandbox Code Playgroud)

我使用Python编写的以下测试平台来验证它是否正常工作:

tests = [
    ('01010', False),
    ('abc', True),
    ('A0c', True),
    ('A0c-', False),
    ('-A0c', False),
    ('A-0c', True),
    ('o123456701234567012345670123456701234567012345670123456701234567', False),
    ('o12345670123456701234567012345670123456701234567012345670123456', True),
    ('', True),
    ('a', True),
    ('0--0', True),
]

import re
regex = re.compile('^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$')
for (s, expected) in tests:
    is_match = regex.match(s) is not None
    print is_match == expected
Run Code Online (Sandbox Code Playgroud)

  • 在 Ruby 中,请分别使用 `\A` 和 `\z` 代替 `^` 和 `$`,因为 Ruby 正则表达式默认是多行的: `\A(?![0-9]+$) (?!-)[a-zA-Z0-9-]{,63}(?&lt;!-)\z`。 (2认同)
  • `01010`是有效标签(RFC 1123).空字符串是无效标签(RFC 1035) (2认同)

Tom*_*ime 12

基于Marks答案的Javascript正则表达式:

pattern = /^(?![0-9]+$)(?!.*-$)(?!-)[a-zA-Z0-9-]{1,63}$/g;
Run Code Online (Sandbox Code Playgroud)


mec*_*oup 7

k8s API 使用正则表达式进行响应,用于验证例如符合 RFC 1123 的字符串:

\n
(\xe2\x8e\x88 minikube:default)\xe2\x9e\x9c  cloud-app git:(mc/72-org-ns-names) \xe2\x9c\x97 k create ns not-valid1234234$%\nThe Namespace "not-valid1234234$%" is invalid: metadata.name: \nInvalid value: "not-valid1234234$%": a lowercase RFC 1123 label must consist of lower case \nalphanumeric characters or '-', and must start and end with an alphanumeric character \n(e.g. 'my-name',  or '123-abc', regex used for validation is\n '[a-z0-9]([-a-z0-9]*[a-z0-9])?')\n
Run Code Online (Sandbox Code Playgroud)\n


Bil*_*ole 5

值得注意的是,DNS 标签和主机名组件的规则略有不同。最值得注意的是:“_”在主机名的任何组成部分中都不合法,但它是用于 SRV 记录等标签的标准部分。

一种更具可读性和可移植性的方法是要求一个字符串来匹配这两个POSIX ERE:

^([[:alnum:]][[:alnum:]\-]{0,61}[[:alnum:]]|[[:alpha:]])$
^.*[[:^digit:]].*$
Run Code Online (Sandbox Code Playgroud)

这些应该易于在任何兼容标准的 ERE 实现中使用。Python 示例中的 Perl 风格回溯已广泛使用,但存在一个问题,即在它看起来有效的地方并不完全相同。哎哟。

原则上可以用这两条线制作一个 ERE,但它会很长且笨重。第一行处理除全数字禁令之外的所有规则,第二行则终止这些规则。