Вернуть только ОДНУ строку при использовании регулярных выражений в Python

Я работаю над простой программой, которая извлекает ссылки с данного веб-сайта и помещает их в список. После этого извлеченные URL-адреса в списке «todo» постепенно анализируются таким же образом.

Основная программа работает, но в следующей версии я просто хочу извлечь основные страницы и игнорировать нижнюю часть (например, «www.stackoverflow.com», НО НЕ «www.stackoverflow.com/questions/ask»)

Я пытался использовать функцию re.findall, но поскольку это объект list, она разрушает структуру моего повторяемого списка дел.

Есть ли возможность просто вернуть строку при использовании регулярных выражений?

soup = BeautifulSoup(handle, 'html.parser')
newlinks = soup.find_all('a')

for link in newlinks:
    todo.append( re.findall('(http://.+)/', link.get('href')) )

person ash bounty    schedule 09.03.2016    source источник
comment
Попробуйте todo.extend(), если вам не нужен вложенный список   -  person OneCricketeer    schedule 09.03.2016
comment
Хорошо, работает :-) Но есть ли другой (может быть, более умный) способ отрезать / blablabla /, чем я? Мне кажется настолько неправильным, что я использую re.findall, хотя, очевидно, в link.get ('href') есть только одна строка, которая соответствует моему регулярному выражению.   -  person ash bounty    schedule 09.03.2016
comment
Если вы используете Python 3, кажется, что модуль urllib.parse может иметь то, что вы хотите. Я обновил свой ответ некоторыми деталями.   -  person Blckknght    schedule 09.03.2016
comment
@Blckknght Отличная альтернатива, спасибо!   -  person ash bounty    schedule 09.03.2016


Ответы (1)


Если вам нужно только одно совпадение для каждой входной строки, не используйте findall, чьей целью является поиск множества совпадений.

Вместо этого используйте re.match(pattern, text), чтобы получить объект match. Убедитесь, что возвращаемое значение не None (это означает, что совпадение не найдено), затем вызовите group(1), чтобы получить совпавшую группу.

Обратите внимание, что ваш шаблон на самом деле не делает то, что вы говорите, что хотите. Если вы хотите сопоставить только начальную часть URL-адреса (включая домен, но не путь), вам необходимо исключить косые черты из повторяющейся части шаблона. Я бы использовал '(http://[^/]+)/'. Другим вариантом было бы нежадное повторение с использованием +? вместо +.

Если вы хотите отказаться от всего подхода RegEx к обработке вашего URL-адреса, вы можете попробовать вместо этого использовать модуль urllib. Вызов urllib.parse.urlsplit разбивает URL-адрес на следующие части: <scheme>://<netloc>/<path>?<query>#<fragment>. (Это может быть новая функция в Python 3, хотя я в этом не уверен. Модули urllib были немного переставлены между версиями.)

person Blckknght    schedule 09.03.2016
comment
Спасибо, это очень помогло! Раньше я никогда не использовал re.match, но думаю, что теперь он у меня есть. Сначала мне нужно создать объект соответствия [mainurl = re.match (regex, link.get ('href'))]. Затем я должен убедиться, что объект не равен None [если mainurl равен None: continue]. И, наконец, я добавляю строку в свой список задач [todo.append (mainurl.group (1))]. Я прав? - person ash bounty; 09.03.2016
comment
Да, я бы так и поступил. Если вам больше нечего делать внутри цикла, вы можете изменить логику if и сделать if mainurl is not None: todo.append(mainurl.group(1)) - person Blckknght; 09.03.2016
comment
Большой! Большое спасибо! - person ash bounty; 09.03.2016