Во-первых, вы должны уточнить, имеете ли вы в виду:
- метки отдельных доменных имен
- полных доменных имен (то есть несколько разделенных точками меток)
- имена хостов
Причина, по которой необходимо проводить различие, заключается в том, что метка может технически включать любые символы, включая символы NUL, @
и '.
'. DNS поддерживает 8 бит, и вполне возможно иметь файл зоны, содержащий запись, читающую "an\0odd\.l@bel
". Конечно, это не рекомендуется, не в последнюю очередь потому, что людям будет трудно отличить точку внутри ярлыка от этих разделяющих ярлыков, но это является законным.
Однако для URL требуется имя хоста в них, и они регулируются RFC 952 и 1123. Допустимые имена хоста являются подмножеством домен имен. В частности, разрешены только буквы, цифры и дефис. Кроме того, первый и последний символы не могут быть дефисами. RFC 952 не разрешил номер для первого символа, но RFC 1123 впоследствии смягчил это.
Таким образом:
a
- действует
0
- действует
a-
- недействительно
a-b
- действует
xn--dasdkhfsd
- действителен (кодировка IDN в виде пункода)
Вне головы, я не думаю, что можно сделать недействительным пример a-
с помощью одного простого регулярного выражения. Лучшее, что я могу придумать, чтобы проверить single host label:
if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $label) &&
!preg_match('/-$/', $label))
{
# label is legal within a hostname
}
Чтобы еще больше усложнить ситуацию, некоторые записи доменных имен (обычно SRV
записей) используют метки с префиксом подчеркивания, например, _sip._udp.example.com
. Это не имена хостов, но допустимые доменные имена.