Развитие к Регулярному выражению для соответствия имени хоста или IP-адресу? и использование Ограничений на допустимые имена хостов как ссылка, каков самый читаемый, краткий способ соответствовать/проверять hostname/fqdn (полностью определенное доменное имя) в Python? Я ответил своей попыткой ниже, приветствующиеся улучшения.
import re
def is_valid_hostname(hostname):
if len(hostname) > 255:
return False
if hostname[-1] == ".":
hostname = hostname[:-1] # strip exactly one dot from the right, if present
allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
return all(allowed.match(x) for x in hostname.split("."))
гарантирует, что каждый сегмент
Он также избегает двойного отрицания ( не запрещено
), и если имя хоста
заканчивается на .
, это тоже нормально. Он завершится (и должен) завершиться ошибкой, если имя хоста
заканчивается более чем одной точкой.
Обрабатывать каждую метку DNS отдельно, исключая недопустимые символы и обеспечивая ненулевую длину.
def isValidHostname(hostname):
disallowed = re.compile("[^a-zA-Z\d\-]")
return all(map(lambda x: len(x) and not disallowed.search(x), hostname.split(".")))
Мне нравится полнота ответа Тима Пицкера, но я предпочитаю выгрузить часть логики из регулярных выражений для удобства чтения. Честно говоря, мне пришлось поискать значение этих частей (?
«нотации расширения». Кроме того, я считаю, что подход «двойного отрицания» более очевиден, поскольку он ограничивает ответственность регулярного выражения до просто нахожу какой-либо недопустимый символ. Мне нравится, что re.IGNORECASE позволяет сократить регулярное выражение.
Итак, вот еще один снимок; он длиннее, но читается как проза. Полагаю, «читабельный» несколько расходится с «кратким» ". Я считаю, что все ограничения валидации, упомянутые в цепочке, уже учтены:
def isValidHostname(hostname):
if len(hostname) > 255:
return False
if hostname.endswith("."): # A single trailing dot is legal
hostname = hostname[:-1] # strip exactly one dot from the right, if present
disallowed = re.compile("[^A-Z\d-]", re.IGNORECASE)
return all( # Split by labels and verify individually
(label and len(label) <= 63 # length is within proper range
and not label.startswith("-") and not label.endswith("-") # no bordering hyphens
and not disallowed.search(label)) # contains only legal characters
for label in hostname.split("."))
Если вы хотите проверить имя существующего хоста, лучший способ - попытаться разрешить его. Вы никогда не напишете регулярное выражение для обеспечения такого уровня проверки.