2010-05-24 33 views
9

我正在使用Python,并希望一个简单的API或正则表达式来检查域名的有效性。根据有效性,我是句法上的有效性,而不是域名是否确实存在于互联网上。检查字符串中的有效域名?

+0

为什么?如果这是电子邮件,则应通过为MX记录执行DNS查询来检查真实有效性,而不是通过regexp进行检查。 – Kimvais 2010-05-24 05:33:56

+5

不是。查找已知无效名称没有任何好处,这只是浪费时间和资源。另外,您不需要MX记录来发送电子邮件,A记录就足够了。 – Synchro 2012-03-22 09:50:54

+0

似乎它已经讨论[这里](http://stackoverflow.com/questions/1128168/validation-for-url-domain-using-regex-rails)。 – Incognito 2010-05-24 05:28:44

回答

13

如果是一个以点分隔的标识符列表(每个标签不超过63个字符),并且由字母,数字和破折号(无下划线)组成,则任何域名都是(语法上)有效的。

所以:

r'[a-zA-Z\d-]{,63}(\.[a-zA-Z\d-]{,63})*' 

将是一个开端。当然,现在可能会允许一些非Ascii字符(最近的一次开发),这会改变参数 - 你需要处理这些吗?

+0

可以用连字符开始/结束标识符吗? – Amarghosh 2010-05-24 05:32:04

+0

谢谢!不,我不需要一些基本的完整性检查,以确保它不包含任何黑名单字符,如'! “等 – demos 2010-05-24 07:06:25

+0

亚历克斯,我知道你是一个appengine大师,请帮我这个: http:// stackoverflow。com/questions/2894808/creating-auto-incrementing-column-in-google-appengine 在此先感谢! – demos 2010-05-24 07:07:25

5
r'^(?=.{4,255}$)([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]\.)+[a-zA-Z0-9]{2,5}$' 
  • 先行确保它具有最小的4(a.in)和长度之间1〜63个,最多255个字符
  • 一个或多个标签(由句点分隔),开始和结束带有字母数字字符,并在中间包含字母数字字符和连字符。
  • 随之而来的是顶级域名(博物馆,其最大长度为5)
+1

这不能存储punycode。Th e最短的西里尔文脚本双字母顶级域是punycode中的6个字母。 – kaleissin 2013-03-21 11:08:21

+2

博物馆是6个字符,而不是5个。 – 2013-10-29 00:49:18

+0

对预期的TLD长度进行硬编码是一个糟糕的主意,尤其是现在IDN TLD正在编码出来并因此出现比5更长的时间。 – 2015-01-16 17:11:58

1

请注意,虽然你可以做东西正则表达式来测试有效的域名最可靠方式是实际尝试解析名称(以socket.getaddrinfo):

from socket import getaddrinfo 

result = getaddrinfo("www.google.com", None) 
print result[0][4] 

注意,从技术上这可以让你开到DOS(如果有人提出无效域名数千个,这可能需要一段时间来解决无效南es),但你可以简单地限制某人尝试这一点。

这样做的好处是它会将“hotmail.con”视为无效(而不是“hotmail.com”),而正则表达式会说“hotmail.con”有效。

+2

这实际上是一个单独的问题,并不是一个很好的答案。鉴于过去曾经使用过DNS,在使用DNS之前检查一个字符串是否至少是有效的,这只是一个明智的做法,加上它比DNS查找快几个数量级。这类似于运行代码来查看它是否是恶意的! – Synchro 2012-03-22 09:45:56

+0

这不能用于验证即将创建的域名,只能用于已有的域名。 – nerdoc 2015-07-23 13:08:18

+0

为什么有效的网址如“https:// google.com /'返回错误? – 2016-09-15 23:09:07

0

我一直在使用这样的:

(r'(\.|\/)(([A-Za-z\d]+|[A-Za-z\d][-])+[A-Za-z\d]+){1,63}\.([A-Za-z]{2,3}\.[A-Za-z]{2}|[A-Za-z]{2,6})') 

,确保其符合或者点后(WWW)或/(HTTP://)和破折号仅发生名称内,以符合这样的后缀作为gov.uk也是。

0

在这一点上,答案都与规范相当过时。我相信下面将正确匹配当前的规格:

r'^(?=.{1,253}$)(?!.*\.\..*)(?!\..*)([a-zA-Z0-9-]{,63}\.){,127}[a-zA-Z0-9-]{1,63}$'