Что такое регулярное выражение, которое будет соответствовать действительному имени домена без поддоменов?

Сначала извините за 10 000-й вопрос в RegEx,

Я понимаю, что есть другие вопросы, связанные с доменом, но регулярное выражение либо не работает должным образом, слишком сложно, либо для URL-адресов с субдоменами, протоколами и файловыми путями.

Mine проще, мне нужно проверить доменное имя:

google.com

stackoverflow.com

Итак, домен в его самой сырой форме - даже не поддомен, такой как www.

  • Символы должны быть a-z | A-Z | 0-9 и период (.) и тире (-)
  • Часть имени домена не должна начинаться или заканчиваться тире (-) (например, -google-.com)
  • Часть доменного имени должна быть длиной от 1 до 63 символов
  • Расширение (TLD) теперь может быть чем-то под # 1 правилами, я могу подтвердить их позже, это должно быть 1 или более символов, но

Изменить: TLD, по-видимому, составляет 2-6 символов, поскольку он стоит

нет. 4: TLD действительно должен быть помечен как "субдомен", так как он должен включать такие вещи, как .co.uk - я бы предположил, что единственная возможная проверка (кроме проверки списка) будет "после первой точки там должен быть один или несколько символов по правилам # 1

Большое спасибо, поверьте мне, я попробовал!

Ответ 1

Ну, он довольно простой немного скромен, чем выглядит (см. комментарии), учитывая ваши особые требования:

/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/

Но обратите внимание, что это отклонит множество допустимых доменов.

Ответ 2

Я знаю, что это немного старый пост, но во всех регулярных выражениях здесь отсутствует один очень важный компонент: поддержка доменных имен IDN.

Доменные имена IDN начинаются с xn--. Они включают расширенные символы UTF-8 в доменных именах. Например, знаете ли вы, что "♡.com" является допустимым доменным именем? Да, "любовь сердце точка ком"! Чтобы проверить доменное имя, вам нужно разрешить http://xn-- c6h.com/ пройти проверку.

Обратите внимание, что для использования этого регулярного выражения вам необходимо преобразовать домен в нижний регистр, а также использовать библиотеку IDN, чтобы обеспечить кодирование доменных имен в ACE (также известное как "ASCII-совместимое кодирование"). Одна хорошая библиотека - это GNU-Libidn.

idn (1) - это интерфейс командной строки для библиотеки интернационализированных доменных имен. В следующем примере имя хоста в UTF-8 преобразуется в кодировку ACE. Полученный URL-адрес https://nic. xn-- flw351e/ можно затем использовать в качестве ACE-кодированного эквивалента https://nic. 谷 歌/.

  $ idn --quiet -a nic.谷歌
  nic.xn--flw351e

Это волшебное регулярное выражение должно охватывать большинство доменов (хотя я уверен, что есть много допустимых краевых случаев, которые я пропустил):

^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$

При выборе регулярного выражения проверки домена вы должны увидеть, соответствует ли домен следующему:

  1. xn-- stackoverflow.com
  2. StackOverflow. xn-- ком
  3. stackoverflow.co.uk

Если эти три домена не проходят, ваше регулярное выражение может не разрешать допустимые домены!

Посетите страницу поддержки интернационализированных доменных имен в Oracle International Language Language Guide для получения дополнительной информации.

Не стесняйтесь попробовать регулярное выражение здесь: http://www.regexr.com/3abjr

ICANN хранит список делегированных доменов, который можно использовать для просмотра некоторых примеров доменов IDN.


Редактировать:

 ^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?([a-z0-9][a-z0-9\-]{0,60}|[a-z0-9-]{1,30}\.[a-z]{2,})$

Это регулярное выражение остановит домены, которые имеют "-" в конце имени хоста как помеченные как действительные. Кроме того, он позволяет неограниченное количество поддоменов.

Ответ 3

Мой RegEx следующий:

^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}\.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}\.[a-zA-Z]{2,3})$

это нормально для i.oh1.me и для wow.british-library.uk

UPD

Вот обновленное правило

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

Regular expression visualization

https://www.debuggex.com/r/y4Xe_hDVO11bv1DV

теперь он проверяет наличие - или _ в начале или конце метки домена.

Ответ 4

Моя ставка:

^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$

Разъяснения:

Доменное имя создается из сегментов. Вот один сегмент (кроме финального):

[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?

Он может иметь 1-63 символа, не начинается или не заканчивается символом "-".

Теперь добавьте '.' к нему и повторить хотя бы один раз:

(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+

Затем присоедините конечный сегмент длиной 2-63 символов:

[a-z0-9][a-z0-9-]{0,61}[a-z0-9]

Проверьте здесь: http://regexr.com/3au3g

Ответ 5

Просто небольшая коррекция - последняя часть должна быть до 6. Следовательно,

^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,6}$

Самый длинный TLD museum (6 символов) - http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains

Ответ 6

Этот ответ относится к доменным именам (включая служебные RR), а не к именам хостов (например, к имени хоста электронной почты).

^(?=.{1,253}\.?$)(?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?<!-)(?:\.|$)){2,}$

Это в основном mkyong ответ и дополнительно:

  • Максимальная длина 255 октетов, включая префиксы длины и нулевой корень.
  • Разрешить трейлинг "." для явного днс рута.
  • Разрешить ведущие '_' для RR домена службы (ошибки: не применяет максимум 15 знаков для меток _, и при этом не требуется по крайней мере один домен выше RR службы)
  • Соответствует всем возможным TLD.
  • Не захватывает метки поддоменов.

По частям

Посмотрите, ограничьте максимальную длину от ^ $ до 253 символов с необязательным конечным литералом '.'

(?=.{1,253}\.?$)

Посмотрите, следующий символ не является "-", и ни один "_" не следует за любыми символами перед следующим ".". То есть, убедитесь, что первый символ метки не является "-", и только первый символ может быть "_".

(?!-|[^.]+_)

От 1 до 63 разрешенных символов на ярлык.

[A-Za-z0-9-_]{1,63}

Смотри сзади, предыдущий символ не '-'. То есть, убедитесь, что последний символ метки не является '-'.

(?<!-)

Принудительно '.' в конце каждого ярлыка, кроме последнего, где это необязательно.

(?:\.|$)

Главным образом, в сочетании с вышеизложенным, для этого требуются как минимум два уровня домена, что не совсем правильно, но обычно является разумным допущением. Измените с {2,} на +, если вы хотите разрешить использование TLD или неквалифицированных относительных поддоменов через (например, localhost, myrouter, to.)

(?:(?!-|[^.]+_)[A-Za-z0-9-_]{1,63}(?<!-)(?:\.|$)){2,}

Модульные тесты для этого выражения.

Ответ 7

Принятый ответ не работает для меня, попробуйте следующее:

^ ((-) [A-Za-z0-9 -] {1,63} (<?! -?!.) \) + [A-Za-Z] {2,6} $

Посетите Unit Test Случаи для проверки.

Ответ 8

Спасибо за указание правильного направления в решениях проверки доменных имен в других ответах. Доменные имена могут быть проверены различными способами.

Если вам нужно проверить домен IDN в удобной для человека форме, регулярное выражение \p{L} поможет. Это позволяет сопоставить любой символ на любом языке.

Обратите внимание, что последняя часть также может содержать дефисы ! Так как китайские имена, закодированные в Punycode, могут содержать символы Unicode в tld.

Я пришел к решению, которое будет соответствовать, например:

  • google.com
  • masełkowski.pl
  • maselkowski.pl
  • m.maselkowski.pl
  • www.masełkowski.pl.com
  • xn--masekowski-d0b.pl
  • 中国 互联 网络 信息 中心. 中国
  • Xn - fiqa61au8b7zsevnm8ak20mc4a87e.xn - fiqs8s

Regex это:

^[0-9\p{L}][0-9\p{L}-\.]{1,61}[0-9\p{L}]\.[0-9\p{L}][\p{L}-]*[0-9\p{L}]+$

Проверьте и настройте здесь

ПРИМЕЧАНИЕ. Это регулярное выражение является вполне допустимым, так как текущий набор доменных имен разрешен.

ОБНОВЛЕНИЕ: еще более упрощенный, поскольку a-aA-Z\p{L} такой же, как просто \p{L}

ПРИМЕЧАНИЕ 2. Единственная проблема заключается в том, что он будет сопоставлять домены с двойными точками в нем..., например, masełk..owski.pl. Если кто-нибудь знает, как это исправить, пожалуйста, улучшите.

Ответ 9

^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,7}$

[domain - строчные буквы и только 0-9] [может иметь дефис] + [только для нижнего регистра, должно быть длиной от 2 до 7 букв]
http://rubular.com/ является блестящим для тестирования регулярных выражений!
Изменить: Обновлен TLD максимум до 7 символов для ".rentals", как указал Дэн Кэддиган.

Ответ 10

Недостаточно репутации для комментариев. В ответ на решение paka я обнаружил, что мне нужно настроить три элемента:

  • Символы и подчеркивание были перемещены из-за того, что тире интерпретируется как диапазон (как в "0-9" ).
  • Добавлена ​​полная остановка для доменных имен со многими субдоменами
  • Увеличена потенциальная длина для TLD до 13

До:

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

После:

^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][-_\.a-zA-Z0-9]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,13}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$

Ответ 11

^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]+(\.[a-zA-Z]+)$

Ответ 12

^((localhost)|((?!-)[A-Za-z0-9-]{1,63}(?<!-)\.)+[A-Za-z]{2,253})$

Спасибо @mkyong за основу для моего ответа. Я изменил его, чтобы поддерживать более приемлемые метки.

Кроме того, "localhost" является технически допустимым доменным именем. Я изменю этот ответ, чтобы разместить интернационализированные доменные имена.

Ответ 13

Для новых gTLD

/^((?!-)[\p{L}\p{N}-]+(?<!-)\.)+[\p{L}\p{N}]{2,}$/iu

Ответ 14

Вот полный код с примером:

<?php
function is_domain($url)
{
    $parse = parse_url($url);
    if (isset($parse['host'])) {
        $domain = $parse['host'];
    } else {
        $domain = $url;
    }

    return preg_match('/^(?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63}$/', $domain);
}

echo is_domain('example.com'); //true
echo is_domain('https://example.com'); //true
echo is_domain('https://.example.com'); //false
echo is_domain('https://localhost'); //false

Ответ 15

/^((([a-zA-Z]{1,2})|([0-9]{1,2})|([a-zA-Z0-9]{1,2})|([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]))\.)+[a-zA-Z]{2,6}$/
  • ([a-zA-Z]{1,2}) → для принятия только двух символов.

  • ([0-9]{1,2}) → для принятия только двух чисел

если что-либо превысит два ([a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]), это регулярное выражение позаботится об этом.

Если мы хотим выполнить сопоставление, по крайней мере, один раз + будет использоваться.

Ответ 16

^ [A-Za-Z0-9] [- A-Za-Z0-9] + [A-Za-Z0-9] [AZ] {2,3} ([AZ] {2,.. 3})? (. [AZ] {2,3})? $

Примеры, которые работают:

stack.com
sta-ck.com
sta---ck.com
9sta--ck.com
sta--ck9.com
stack99.com
99stack.com
sta99ck.com

Он также будет работать для расширений

.com.uk
.co.in
.uk.edu.in

Примеры, которые не будут работать:

-stack.com

он будет работать даже с самым длинным расширением домена ".versicherung"

Ответ 17

Как уже указывалось, это не очевидно, чтобы сказать поддоменов в практическом смысле. Мы используем это регулярное выражение для проверки доменов, которые встречаются в дикой природе. Он охватывает все случаи практического использования, о которых я знаю. Новые приветствуются. Согласно нашим рекомендациям, это позволяет избежать групп захвата и жадного сопоставления.

^(?!.*?_.*?)(?!(?:[\d\w]+?\.)?\-[\w\d\.\-]*?)(?![\w\d]+?\-\.(?:[\d\w\.\-]+?))(?=[\w\d])(?=[\w\d\.\-]*?\.+[\w\d\.\-]*?)(?![\w\d\.\-]{254})(?!(?:\.?[\w\d\-\.]*?[\w\d\-]{64,}\.)+?)[\w\d\.\-]+?(?<![\w\d\-\.]*?\.[\d]+?)(?<=[\w\d\-]{2,})(?<![\w\d\-]{25})$

Доказательство и объяснение: https://regex101.com/r/FLA9Bv/9

При проверке доменов можно выбрать один из двух подходов.

Соответствие полному доменному имени (теоретическое определение, редко встречающееся на практике):

  • длина не более 253 символов (согласно RFC-1035/3.1, RFC-2181/11)
  • не более 63 символов на этикетку (согласно RFC-1035/3.1, RFC-2181/11)
  • разрешены любые символы (согласно RFC-2181/11)
  • TLD не могут быть полностью числовыми (согласно RFC-3696/2)
  • Полные доменные имена могут быть записаны в полной форме, которая включает корневую зону (конечная точка)

Практическое/консервативное сопоставление FQDN (практическое определение, ожидаемое и поддерживаемое на практике):

  • соответствие книг со следующими исключениями/дополнениями
  • допустимые символы: [a-zA-Z0-9.-]
  • метки не могут начинаться или заканчиваться дефисами (согласно RFC-952 и RFC-1123/2.1)
  • Минимальная длина TLD - 2 символа, максимальная длина - 24 символа в соответствии с текущими записями.
  • не соответствует конечной точке