Проблема с регулярными выражениями в python

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

Я скомпилировал регулярное выражение:

regex = re.compile(r''' <h[0-9]>\s? (<a[ ]href="[A-Za-z0-9.]*">)?\s? [A-Za-z0-9.,:'"=/?;\s]*\s? [A-Za-z0-9.,:'"=/?;\s]? ''', re.X) 

Когда я запускаю это в python reg ex. Тестер прекрасно работает.

Пример данных:

 <body> <h1>Dog </h1> <h2>Cat </h2> <h3>Fancy </h3> <h1>Tall cup of lemons</h1> <h1><a href="dog.com">Dog thing</a></h1> </body> 

Теперь, в REDemo, он работает чудесно.

Однако, когда я помещаю его в свой код python, он печатает только <a href="dog.com">

Вот мой код на Python, я не уверен, что я делаю что-то неправильно или что-то потеряно в переводе. Я ценю вашу помощь.

 stories=[] response = urllib2.urlopen('http://apricotclub.org/duh.html') html = response.read().lower() p = re.compile('<h[0-9]>\\s?(<a href=\"[A-Za-z0-9.]*\">)?\\s?[A-Za-z0-9.,:\'\"=/?;\\s]*\\s?[A-Za-z0-9.,:\'\"=/?;\\s]?') stories=re.findall(p, html) for i in stories: if len(i) >= 5: print i 

Следует также отметить, что когда я (<a href=\"[A-Za-z0-9.]*\">)? из обычного выражения он отлично работает для строк без ссылки <hN> .

7 Solutions collect form web for “Проблема с регулярными выражениями в python”

В течение последних нескольких дней этот вопрос задавался в нескольких формах, поэтому я хочу сказать это очень четко.

В: Как анализировать HTML с помощью регулярных выражений?

A: Пожалуйста, не делайте этого.

Используйте BeautifulSoup , html5lib или lxml.html . Пожалуйста.

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

Недостаток – это не очень быстро. Есть lxml для синтаксического анализа хорошо сформированного html, но вы действительно должны использовать BeautifulSoup, если вы не на 100% уверены, что ваш вход всегда будет хорошо сформирован.

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

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

Но действительно, вы должны использовать настоящий парсер.

Пожалуйста, не ругайте вручную html в python! Есть много лучших вариантов; Я бы порекомендовал замечательный BeautifulSoup

Основываясь на ответах до сих пор:

Лучше всего использовать синтаксический анализатор. Он может охватывать множество случаев и элегантным способом. Я пробовал BeautifulSoup, и мне это очень нравится. Также прост в использовании, с большим учебником.

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

 p = re.compile(r'<(h[0-9])>(.+?)</\1>', re.IGNORECASE | re.DOTALL) stories = re.findall(p, html) for i in stories: print i 

Я использовал beautifulsoup для анализа вашего желаемого HTML. У меня есть вышеуказанный HTML-код в файле с именем foo.html, а позже – как файл.

 from BeautifulSoup import BeautifulSoup H_TAGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] def extract_data(): """Extract the data from all headers in a HTML page.""" f = open('foo.html', 'r+') html = f.read() soup = BeautifulSoup(html) headers = [soup.findAll(h) for h in H_TAGS if soup.findAll(h)] lst = [] for x in headers: for y in x: if y.string: lst.append(y.string) else: lst.append(y.contents[0].string) return lst 

Вышеуказанная функция возвращает:

 >>> [u'Dog ', u'Tall cup of lemons', u'Dog thing', u'Cat ', u'Fancy '] 

Вы можете добавить любое количество тегов заголовков в список h_tags. Я взял все заголовки. Если вы можете легко решить проблему с помощью BeautifulSoup, тогда лучше использовать его. 🙂

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

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

 import re html = ''' <body> <h1>Dog </h1> <h2>Cat </h2> <h3>Fancy </h3> <h1>Tall cup of lemons</h1> <h1><a href="dog.com">Dog thing</a></h1> </body> ''' p = re.compile(r''' <(?P<header>h[0-9])> # store header tag for later use \s* # zero or more whitespace (<a\shref="(?P<href>.*?)">)? # optional link tag. store href portion \s* (?P<title>.*?) # title \s* (</a>)? # optional closing link tag \s* </(?P=header)> # must match opening header tag ''', re.IGNORECASE + re.VERBOSE) stories = p.finditer(html) for match in stories: print '%(title)s [%(href)s]' % match.groupdict() 

Вот несколько хороших ресурсов регулярного выражения:

  • Регулярное выражение Python HOWTO
  • Regular-Expressions.info
  • Многострочное регулярное выражение python
  • Использование регулярного выражения для запятой выделяет большое количество в системе нумерации южной Азии
  • Анализ IP-адреса / сети из текстового файла с использованием python
  • Поиск и замена списка слов в файле с использованием регулярного выражения в Python
  • Perl Compatible Regular Expression (PCRE) в Python
  • Правильные выражения Python имеют эквивалент атомной группировки Ruby?
  • Найти файл в каталоге с помощью python путем частичного имени
  • Python сравнивает строку с несколькими регулярными выражениями
  • Python - лучший язык программирования в мире.