2017-02-17 2 views
0

Итак, для некоторого lulz мы с другом играли с идеей фильтрации списка (100k +) URL-адресов для извлечения только родительского домена (например, domain.com) | орг | и т.д. "). Единственное предостережение в том, что они не все красивы и соответствуют формату.Улучшение точности/краткости регулярного выражения для непоследовательной фильтрации URL

Таким образом, некоторые из них могут быть «http://www.domain.com/urlstuff», некоторые из них имеют коды стран, такие как «www.domain.co.uk/urlstuff», в то время как другие могут быть немного более странными, более похожими на «hello.in». con.sistent.urls.com/urlstuff».

Итак, история в стороне, у меня есть регулярное выражение, которое работает:

import re 

firsturl = 'www.foobar.com/fizz/buzz' 
m = re.search('\w+(?=(\..{3}/|\..{2}\..{2}/))\.(.{3}|.{2}\..{2})', firsturl) 

m.group(0) 

, который возвращает:

foobar.com 

Он смотрит первые "/" в конце URL, а затем возвращается два "." перед ним.

Итак, мой запрос, будет ли кто-нибудь из улов кучи ума иметь какую-либо мудрость, чтобы избавиться от того, как это можно сделать с помощью лучшего/короткого регулярного выражения или регулярного выражения, которое не полагается на прямой просмотр «/» внутри Струна?

Оценка за помощь в этом!

+0

Вам действительно нужно использовать 'regex'? –

+0

Как и многие проблемы, существует множество решений. В python легко и pythonic перебирать строки, разделяемые разделителем («.») И просто объединять то, что нам нужно.Итак, я знаю, что это можно сделать легко вне regex, но в контексте регулярного выражения мне интересно, если это можно сделать лучше, чем то, что у меня есть. – RedBarron

ответ

1

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

В вашем объяснении и попытке решения проблемы, я думаю, вы очень упрощаете ее. ДВУ поступают во многих других вариантах, кроме «двухзначных кодов стран» и «трехзначных» других. См. ICANN's list of top-level domains для доступных в настоящее время сотен от 2 до 8 цифр. Кроме того, у вас могут быть URL-адреса без косой черты, а некоторые с несколькими слэшами и точками после имени домена.

Так вот мое решение (see on regex101):

^(?:https?://)?(?:[^/]+\.)*([^/]+\.[a-z]{2,})

То, что вы хотите, захватывается в первой совпадающей группе.

Разбивка:

  • ^(?:https?://)? соответствует возможному протоколу в начале
  • (?:[^/]+\.)* соответствует возможным несколько последовательностей без косых черт, каждый следует точка
  • ([^/]+\.[a-z]{2,}) матчи (и) захватывает один последний не- косой чертой, затем точкой и TLD (2 + буквы)
+0

Спасибо, Брайан, я ценю это много! Он работает на гораздо меньших предположениях и сильнее против непоследовательных строк. Это действительно полезно ^^ – RedBarron

0

Вы можете использовать это регулярное выражение вместо:

import re 
firsturl = 'www.foobar.com/fizz/buzz' 
domain = re.match("(.+?)\/", firsturl).group() 

Обратите внимание, однако, что это будет работать только без 'http://'.