Я использую python и хотел бы, чтобы простой API или регулярное выражение проверяли действительность доменного имени. Под действительностью я подразумеваю синтаксическую действительность, а не от того, действительно ли доменное имя существует в Интернете или нет.
Проверить допустимое доменное имя в строке?
Ответы (5)
Любое доменное имя (синтаксически) допустимо, если оно представляет собой список идентификаторов, разделенных точками, каждый из которых не длиннее 63 символов и состоит из букв, цифр и дефисов (без подчеркивания).
So:
r'[a-zA-Z\d-]{,63}(\.[a-zA-Z\d-]{,63})*'
было бы началом. Конечно, в наши дни могут быть разрешены некоторые символы, отличные от Ascii (совсем недавняя разработка), которые сильно меняют параметры - вам нужно иметь дело с этим?
blah._domainkey.example.com
.
- person Synchro; 03.09.2012
r'^(?=.{4,255}$)([a-zA-Z0-9][a-zA-Z0-9-]{,61}[a-zA-Z0-9]\.)+[a-zA-Z0-9]{2,5}$'
- Lookahead гарантирует, что он имеет минимум 4 (
a.in
) и максимум 255 символов. - Одна или несколько меток (разделенных точками) длиной от 1 до 63, начинающихся и заканчивающихся буквенно-цифровыми символами и содержащих буквенно-цифровые символы и дефисы в середине.
- За которым следует доменное имя верхнего уровня (максимальная длина которого составляет 5 для музея)
Обратите внимание: несмотря на то, что с регулярными выражениями можно что-то делать, наиболее надежный способ проверки действительных доменных имен — это попытаться разрешить имя (с помощью socket.getaddrinfo):
from socket import getaddrinfo
result = getaddrinfo("www.google.com", None)
print result[0][4]
Обратите внимание, что технически это может оставить вас открытыми для DoS (если кто-то отправит тысячи недействительных доменных имен, может потребоваться некоторое время для разрешения недействительных имен), но вы можете просто ограничить количество тех, кто пытается это сделать.
Преимущество этого в том, что он поймает «hotmail.con» как недействительный (вместо, скажем, «hotmail.com»), тогда как регулярное выражение скажет, что «hotmail.con» действителен.
Я использовал это:
(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.
На данный момент все ответы довольно устарели со спецификацией. Я считаю, что приведенное ниже будет правильно соответствовать текущей спецификации:
r'^(?=.{1,253}$)(?!.*\.\..*)(?!\..*)([a-zA-Z0-9-]{,63}\.){,127}[a-zA-Z0-9-]{1,63}$'