我正在尝试编写一些代码,这些代码将采用"假定"的域名,并根据RFC 1035对其进行验证。例如,它需要满足以下规则:
- 域包含的总字符数不超过 253 个
- 域字符集仅
[a-z0-9-]
(输入时将小写域) - 域不能包含两个连续的破折号(例如:
google--com.com
) - 最大子域限制为 127
我已经搜索了各种Python模块(例如:tldextract),但无济于事。
如何验证域名是否符合 RFC 1035?
KISS:
import string
VALID_CHARS = string.lowercase + string.digits + '-.'
def is_valid_domain(domain):
if not all(char in VALID_CHARS for char in domain.lower()):
return False
if len(domain) > 253:
return False
if '--' in domain:
return False
if '..' in domain:
return False
return True
聪明的时候也有,但这似乎不是其中之一。
我认为自己
解决这个问题非常简单,只要您只关心 RFC 1035 域。后来的规范允许更多种类的域名,所以这对于现实世界来说是不够的!
这是一个解决方案,它使用正则表达式来匹配遵循 RFC 第 6 页和第 7 页上描述的"首选名称语法"的域名。它处理除具有单个模式的字符数的顶级限制之外的所有内容:
import re
def validate_domain_name(name):
if len(name) > 255: return False
pattern = r"""(?X) # use verbose mode for this pattern
^ # match start of the input
(?: # non-capturing group for the whole name
[a-zA-Z] # first character of first label
(?: # non-capturing group for the rest of the first label
[a-zA-Z0-9-]{,61} # match middle characters of label
[a-zA-Z0-9] # match last character of a label
)? # characters after the first are optional
(?: # non-capturing group for later labels
. # match a dot
[a-zA-Z](?:[a-zA-Z0-9-]{,61}[a-zA-Z0-9])? # match a label as above
)* # there can be zero or more labels after the first
)? # the whole name is optional ("" is valid)
$ # match the end of the input"""
return re.match(pattern, name) is not None # test and return a Boolean