2012-02-13 2 views
2

Я пытаюсь извлечь доменное имя и TLD (если он существует) из строки.regex - извлечения доменного имени и TLD

Для «testing.co.uk» Я хочу иметь массив значений: («тестирование», «CO.UK»)

Для «-testing.c» Я хочу иметь массив значение: ("тестирование")

для "test-ing.co.uk.com" Я хочу иметь массив значений ("тестирование", "cO.UK")

Правила являются простыми:

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

У меня есть это:

  • (\w[-\w]*\w) - первая часть, которая извлекает имя домена (рабочий)
  • \.(\w{2,}(\.?\w{2,})?) - получить TLD (не работает)

ответ

4

Если мы можем сделать предположение о том, что ДВУ не более чем в 2 подразделах длинный, в конце строки (последний подраздел всегда является частью ДВУ) и что средний подраздел i с длиной от 2 до 3 символов. То, что есть хотя бы один подраздел в строке, которая не является TLD, тогда следующее должно соответствовать большинству случаев. Ваше предположение о доменах, требующих все буквенно-цифровые символы с черточкой в ​​середине, является правильным. Каждый сегмент может содержать только 63 символа.

^((?:www\.)?(?:\w[-\w]{0-61}\w|\w)(?:\.\w[-\w]{0-61}\w|\w)*?)\.((?:\w{2-3}\.)?\w+))$ 

Для объяснения:

(?: ) означает матч без захвата, вы можете использовать +, *,? на нем, но он не будет возвращен в ответе

^ и $ матча в начале и конце строки соответственно

{n-m}, как * или +, но соответствует определенному количеству символов

*? означает совпадение 0 или более совпадений, но не является жадным, поэтому соответствует наименьшему количеству раз, которое требуется для действительного соответствия. Это означает, что подразделы, которые потенциально могут быть сопоставлены с любой стороны регулярного выражения, войдут в TLD.

(?:www\.)? это багфикс для коротких доменных имен, таких как www.un.org

(?:\w[-\w]{0-61}\w|\w) гарантирует, что есть по крайней мере один подраздел в доменной части и что каждая секция при макс 63 символов (61 + 2 = 63). Подсекция захватывается внешними скобками. Бит \ \ w в конце решает для краевого случая однобуквенных доменных имен, таких как x.org и i.net.

(?:\.\w[-\w]{0-61}\w)*?|\w) необходимо повторить, так как первый подраздел не может начинаться с точки. Нуль или более из них требуется, но сделать это не жадным поиском.

((?:\w{2-3}\.)?\w+) соответствует TLD согласно приведенным выше правилам. Последний подраздел всегда является частью ДВУ. Правила о том, что составляет TLD второго уровня, более нечеткие.

Это регулярное выражение не является полностью надежным, так как есть несколько исключений, которые нарушают вышеуказанные правила. www.un.com - один из примеров одного домена TLD с коротким доменным именем. gmp.police.uk (Полиция Большого Манчестера) является примером другого домена, где TLD (polic.uk) не будет надлежащим образом сопоставлен (это будет соответствовать uk).

Я увеличил длину сегментов TLD до {2-4}, так как нам нужно включить домены, такие как .info и .mod.uk. Я сократил длину второго сегмента ДВУ до {2-3}, чтобы уменьшить количество несоответствий на четырехбуквенных доменных именах, не так много мы можем сделать с двумя или тремя именами доменных имен, но они будут несовместимы, если домен также содержит подобъект, такой как blog.cat.com

Ниже приведен список некоторых уже существующих TLD, которые могут выделить некоторые из краевых случаев. Я не думаю, что есть какие-либо
http://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
http://en.wikipedia.org/wiki/.uk

+0

Спасибо, ваше сообщение привнесло меня намного ближе к тому, что мне нужно. Похоже, \ w включает символ подчеркивания "_", который нельзя использовать в именах доменов или TLD. – budidino

+1

Я не уверен, почему люди считают этот вопрос правильным, так как он явно не работает: http://rubular.com/r/z4aD5U9I8H Я прикладываю усилия, и это привело меня к собственному ответу, который обрабатывает тот же тест намного лучше. До тех пор, пока кто-то не опубликует что-то, что работает, этот вопрос будет без ответа – budidino

+1

Ответ имеет несбалансированную скобку ")" - https://regex101.com/r/bX3kV8/1 – traxium

-8

После зачистки http:// и https:// из URL, это работает для меня:

(?:www\.)?((?!-)[a-zA-Z0-9-]{2,63}(?<!-))\.?((?:[a-zA-Z0-9]{2,})?(?:\.[a-zA-Z0-9]{2,})?) 

проверить один URL в то время, и если она возвращает два совпадения, я считаю это действительным (так как у меня нет навыков регулярного выражения, чтобы выполнить ту же проверку).

Попробуйте здесь: http://rubular.com/r/CXmWlSuikP

EDIT: Downvoting без обратной связи не помогает никому в этом сообществе. Если этот ответ не подходит для вашего конкретного случая, сообщите об этом. Если вы нашли решение своей проблемы, отправьте ее в качестве ответа.

+0

нет, он не работает – transilvlad

+6

Путь принять предложение @Jamie McGuigan, улучшите его, отправьте и пометьте свой собственный ответ как правильный. – achinda99

+1

@tntu, Какая часть этого не работает? Просто интересно, потому что я собираюсь сделать что-то подобное. – achinda99

Смежные вопросы