Нужна помощь в регулярных выражениях Python - PullRequest
1 голос
/ 01 августа 2010

Мне нужно получить информацию с веб-сайта, который выводит ее случайным образом между <font color="red">needed-info-here</font> ИЛИ <span style="font-weight:bold;">needed-info-here</span>.

Я могу получить ее, когда использую

start = '<font color="red">'
end = '</font>'
expression = start + '(.*?)' + end
match = re.compile(expression).search(web_source_code)
needed_info = match.group(1)

, но затемМне нужно выбрать для извлечения либо <font>, либо <span>, при неудаче, когда сайт использует другой тег.

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

Ответы [ 6 ]

7 голосов
/ 01 августа 2010

Не анализировать HTML с регулярным выражением.

Regex не является подходящим инструментом для решения этой проблемы. Посмотрите BeautifulSoup или lxml .

3 голосов
/ 01 августа 2010

Вы можете объединить две альтернативы с вертикальной чертой:

start = '<font color="red">|<span style="font-weight:bold;">'
end = '</font>|</span>'

, поскольку вы знаете, что тег шрифта всегда будет закрыт </font>, тег span всегда будет </span>.

Тем не менее, рассмотрите возможность использования твердого синтаксического анализатора HTML, такого как BeautifulSoup, вместо того, чтобы разбирать собственные регулярные выражения, для анализа HTML, что в общем случае не подходит для анализа регулярными выражениями.

1 голос
/ 01 августа 2010

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

Вот как ответить на ваш вопрос, используя pyparsing:

html = """ need to get info from a website that outputs it between <font color="red">needed-info-here</font> OR <span style="font-weight:bold;">needed-info-here</span>, randomly.
<font color="white">but not this info</font> and 
<span style="font-weight:normal;">dont want this either</span>
"""

from pyparsing import *

font,fontEnd = makeHTMLTags("FONT")
# only match <font> tags with color="red"
font.setParseAction(withAttribute(color="red"))
# only match <span> tags with given style
span,spanEnd = makeHTMLTags("SPAN")
span.setParseAction(withAttribute(style="font-weight:bold;"))

# define full match patterns, define "body" results name for easy access
fontpattern = font + SkipTo(fontEnd)("body") + fontEnd
spanpattern = span + SkipTo(spanEnd)("body") + spanEnd

# now create a single pattern, matching either of the other patterns
searchpattern = fontpattern | spanpattern

# call searchString, and extract body element from each match
for text in searchpattern.searchString(html):
    print text.body

Печать:

needed-info-here
needed-info-here
1 голос
/ 01 августа 2010
expression = '(<font color="red">(.*?)</font>|<span style="font-weight:bold;">(.*?)</span>)'
match = re.compile(expression).search(web_source_code)
needed_info = match.group(2)

Это выполнит работу, но вы не должны использовать регулярные выражения для анализа html

1 голос
/ 01 августа 2010

Хотя регулярные выражения не ваш лучший выбор для анализа HTML.

Ради образования, вот возможный ответ на ваш вопрос:

start = '<(?P<tag>font|tag) color="red">'
end = '</(?P=tag)>'
expression = start + '(.*?)' + end
0 голосов
/ 01 августа 2010

Я не использовал Python, но если вы сделаете выражения, равные следующим, это должно работать:

/(?P<open><(font|span)[^>]*>)(?P<info>[^<]+)(?P<close><\/(font|span)>)/gi

Затем просто получите доступ к необходимой информации с именем "info".

PS - Я также согласен с правилом «не разбирать HTML с помощью регулярных выражений», но если вы знаете , что оно будет отображаться либо в тегах шрифта, либо в span, то пусть будет так ...

Кроме того, зачем использовать тег шрифта?Я не использовал тег шрифта с тех пор, как выучил CSS.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...