Ответ 1
^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$
Я ищу the regex для проверки имен хостов. Он должен полностью соответствовать стандарту. Прямо сейчас у меня есть
^[0-9a-z]([0-9a-z\-]{0,61}[0-9a-z])?(\.[0-9a-z](0-9a-z\-]{0,61}[0-9a-z])?)*$
но он позволяет использовать последовательные подменю и имена хостов длиной более 255 символов. Если идеальное регулярное выражение невозможно, скажите так.
Изменить/уточнить: поиск Google не показал, что это проблема (или доказанная неразрешимая). Я хочу создать окончательное регулярное выражение, так что никто не должен писать его когда-либо. Если диалекты имеют значение, я хочу, чтобы для каждой из них была версия, в которой это можно сделать.
^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|-){0,61}[0-9A-Za-z])?)*\.?$
Утвержденный ответ проверяет недопустимые имена хостов, содержащие несколько точек (example..com
). Вот регулярное выражение, которое я придумала и которое, я думаю, в точности соответствует тому, что допустимо в соответствии с требованиями RFC (минус окончание ".", Поддерживаемое некоторыми распознавателями для короткого замыкания относительного именования и принудительного разрешения полного доменного имени).
Spec:
<hname> ::= <name>*["."<name>]
<name> ::= <letter-or-digit>[*[<letter-or-digit-or-hyphen>]<letter-or-digit>]
Regex:
^([a-zA-Z0-9](?:(?:[a-zA-Z0-9-]*|(?<!-)\.(?![-.]))*[a-zA-Z0-9]+)?)$
Я тестировал довольно много перестановок сам, я думаю, что это точно.
Это регулярное выражение также не выполняет проверку длины. RFC требует ограничения длины меток между точками и именами, но длины можно легко проверить как второй и третий проходы после проверки по этому регулярному выражению, путем проверки полной длины строки и разделения на "." и проверка длины всех подстрок. Например, в JavaScript проверка длины метки может выглядеть следующим образом: "example.com".split(".").reduce(function (prev, curr) { return prev && curr.length <= 63; }, true)
.
Альтернативное регулярное выражение (без негативного взгляда, любезно предоставлено HTML Living Standard):
^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$
Ваш ответ был относительно близким.
Но см.
Для имени хоста RE, что perl-модуль производит
(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]|[a-zA-Z])[.]?)
Я бы уточнил, чтобы быть более точным:
(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]{0,61})?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-9]{0,61}[a-zA-Z0-9]|[a-zA-Z])[.]?)
При необходимости привязать концы с помощью ^$
к ТОЛЬКО совпадению имен хостов.
Я не думаю, что один RE может выполнить полную проверку, потому что, согласно Wikipedia, длина 255 символов ограничение, которое, я думаю, не может быть включено в тот же RE, по крайней мере, не без тонны изменений, но достаточно просто проверить длину & lt; = 255 до запуска RE.
Взгляните на следующий вопрос. Несколько ответов имеют выражения регулярного выражения для имен хостов
Не могли бы вы указать, на каком языке вы хотите использовать это регулярное выражение? Большинство языков/систем имеют несколько разные варианты регулярных выражений, которые будут влиять на ответы людей.
Как насчет:
^(?=.{1,255})([0-9A-Za-z]|_{1}|\*{1}$)(?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?)*\.?$
для сопоставления только одного '_' (для некоторого SRV) в начале и только одного * (в случае метки для группового символа DN)