Существует ли регулярное выражение для поиска всех предложений вопросов на веб-странице? - PullRequest
1 голос
/ 23 марта 2019

Я пытаюсь извлечь некоторые вопросы с веб-сайта, используя BeautifulSoup, и хочу использовать регулярные выражения для получения этих вопросов из Интернета. Мое регулярное выражение неверно? И как я могу объединить soup.find_all с re.compile?

Я пробовал следующее:

from bs4 import BeautifulSoup
import requests
from urllib.request import urlopen
import urllib
import re

url = "https://www.sanfoundry.com/python-questions-answers-variable-names/"

headers = {'User-Agent':'Mozilla/5.0'}
page = requests.get(url)
soup = BeautifulSoup(page.text, "lxml")
a = soup.find_all("p")

for m in a:
    print(m.get_text())

Теперь у меня есть текст, содержащий вопросы типа «1. Является ли Python чувствительным к регистру при работе с идентификаторами?». Я хочу использовать r "[^.!?] + \?" отфильтровать нежелательный текст, но у меня есть следующая ошибка:

a = soup.find_all("p" : re.compile(r'[^.!?]+\?'))

a = soup.find_all("p" : re.compile(r'[^.!?]+\?'))
                          ^
SyntaxError: invalid syntax

Я проверил свое регулярное выражение на https://regex101.com,, это кажется правильным. Есть ли способ объединить регулярное выражение и soup.find_all вместе?

Ответы [ 2 ]

2 голосов
/ 23 марта 2019

Один из способов найти p элементов, содержащих ? это, чтобы определить функцию критерия:

def criterion(tag):
    return tag.name == 'p' and re.search('\?', tag.text)

и использовать ее в find_all:

pars = soup.find_all(criterion)

Но вы хотите напечатать только вопросы , а не целые абзацы из pars.

Чтобы соответствовать этим вопросам, определите шаблон:

pat = re.compile(r'\d+\.\s[^?]+\?')

(последовательность цифр, точка, пробел, затем последовательность символов, отличных от ? и, наконец, ?).

Обратите внимание, что в общем случае один абзац может содержать несколько вопросов.Таким образом, цикл обработки найденных абзацев должен:

  • использовать findall, чтобы найти всех вопросов в текущем абзаце (в результате получается список найденныхстроки),
  • выведите также все из них в отдельных строках, поэтому следует использовать join с \n в качестве разделителя.

Таким образом, весь цикл должен быть:

for m in pars:
    questions = pat.findall(m.get_text())
    print('\n'.join(questions))
2 голосов
/ 23 марта 2019

Не большой поклонник регулярных выражений, поэтому попробовал это:

for q in a:
   for i in q:
       if '?' in i:
          print(i)

Выход:

1. Is Python case sensitive when dealing with identifiers?
2. What is the maximum possible length of an identifier?
3. Which of the following is invalid?
4. Which of the following is an invalid variable?
5. Why are local variable names beginning with an underscore discouraged?
6. Which of the following is not a keyword?
8. Which of the following is true for variable names in Python?
9. Which of the following is an invalid statement?
10. Which of the following cannot be a variable?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...