2010-05-24 3 views
9

Я использую python и хотел бы простое api или regex проверить правильность имени домена. По действительности я являюсь синтаксической достоверностью, а не тем, действительно ли доменное имя существует в Интернете или нет.Проверьте правильность доменного имени в строке?

+0

По какой причине? Если это, скажем, электронная почта, реальную достоверность следует проверить, выполнив DNS-запрос для записи MX, а не по регулярному выражению. – Kimvais

+5

Нет. Существует нулевая выгода при поиске похожих имен, это просто пустая трата времени и ресурсов. Также вам не нужна запись MX для доставки электронной почты, достаточно записи A. – Synchro

+0

Кажется, это уже обсуждалось [ЗДЕСЬ] (http://stackoverflow.com/questions/1128168/validation-for-url-domain-using-regex-rails). – Incognito

ответ

13

Любое доменное имя является (синтаксически) действительным, если это список идентификаторов, разделенных точками, длиной не более 63 символов и состоящий из букв, цифр и тире (без подчеркивания).

Итак:

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

будет начало. Конечно, в эти дни могут быть разрешены некоторые символы не-Ascii (очень недавняя разработка), которая сильно изменяет параметры - вам нужно иметь дело с этим?

+0

может ли идентификатор начинать/заканчивать дефисом? – Amarghosh

+0

Спасибо! Нет, мне не нужна какая-то базовая проверка здравомыслия, чтобы убедиться, что она не содержит черных списков, таких как «! »и т. д. – demos

+0

Алекс, я знаю, что вы являетесь агентом по приложению, пожалуйста, помогите мне с этим: http: // stackoverflow.com/questions/2894808/create-auto-incrementing-column-in-google-appengine Заранее спасибо! – demos

5
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 для музея)
+1

Это не может хранить punycode. Th e кратчайший двухбуквенный домен верхнего уровня кириллического сценария - 6 букв в punycode. – kaleissin

+2

музей - 6 символов, а не 5. –

+0

Плохая идея жестко кодировать ожидаемую длину TLD, особенно сейчас, когда выходят IDN TLD, которые закодированы и, таким образом, выходят намного дольше, чем 5. –

1

Заметим, что в то время как вы можете сделать что-то с регулярными выражениями, тем самый надежный способ проверки действительных доменных имен это на самом деле пытаюсь разрешить имя (с socket.getaddrinfo):

from socket import getaddrinfo 

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

Обратите внимание, что технически это может оставить вас открытым для атак DoS (если кто-то отправляет тысячи недействительных доменных имен, это может занять некоторое время, чтобы решить недопустимое NAM es), но вы можете просто оценить - ограничить кого-то, кто пытается это сделать.

Преимущество этого в том, что он будет считать «hotmail.con» недействительным (вместо «hotmail.com», скажем), тогда как в регулярном выражении будет указано, что «hotmail.con» действителен.

+2

Это действительно отдельная проблема и не очень хороший ответ на вопрос. Учитывая, что DNS использовался в прошлом для эксплойтов, проверка того, что строка, по крайней мере, действительна до ее использования, является разумной, а также на порядок быстрее, чем поиск DNS. Это похоже на запуск кода, чтобы узнать, злонамерен ли он! – Synchro

+0

Это не может использоваться для проверки имен доменов, которые должны быть созданы, только для уже существующих. – nerdoc

+0

Почему действительный url нравится: 'https: // google.com /' возвращать ошибку? –

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}$' 
Смежные вопросы