Найти - Пользователи
Полная версия: Правильное регулярное выражение для HTML-кода
Начало » Python для новичков » Правильное регулярное выражение для HTML-кода
1
Positive
Здравствуйте.

Есть некий кусок html кода в одну строчку.
<tr bgcolor=ffffff><td>> Текст1</td><td><b>12.22</td></tr><tr bgcolor=EEF4FA><td>> Текст2</td><td><b>12.10</td></tr><tr bgcolor=ffffff><td>> Текст3</td><td><b>10.70</td></tr><tr bgcolor=EEF4FA><td>> Текст4</td><td><b><font color=EEF4FA>_</font>9.15</td></tr>
Мне нужно получить числовые значения для Текст1-4.

Написал такой шаблон:

pattern1 = re.compile(u'(?<=Текст1</td><td><b>)\d{1,2}\.\d{2}')
pattern2 = re.compile(u'(?<=Текст2</td><td><b>)\d{1,2}\.\d{2}')
pattern3 = re.compile(u'(?<=Текст3</td><td><b>)\d{1,2}\.\d{2}')
pattern4 = re.compile(u'(?<=Текст4</td><td><b>)\d{1,2}\.\d{2}')
Работает отлично для Текст1-3, но потом встречается Текст4 и шаблон естественно обламывается из-за вставки <font color=EEF4FA>_</font>.

Можно конечно сделать что-то вроде
pattern4 = re.compile(u'(?<=Текст4</td><td><b>).*?\d{1,2}\.\d{2}')
и потом еще один шаблон для отсечения <font color=EEF4FA>_</font> от Текст4. Но меня не покидает ощущение, что я не полностью использую возможности регулярных выражений и чего-то не знаю.
Можно ли написать один универсальный шаблон для всех Текст1-4?
Dimka665
может стоит использовать модуль HTMLParser?
Positive
Dimka665
может стоит использовать модуль HTMLParser?
Спасибо, я посмотрю, что можно с ним сделать.

Но все-таки хотелось бы понять, можно ли это сделать с помощью re.
shiza
как-нибудь так? =)
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import re

subject = """
<tr bgcolor=ffffff><td>> Текст1</td><td><b>12.22</td></tr>
<tr bgcolor=EEF4FA><td>> Текст2</td><td><b>12.10</td></tr>
<tr bgcolor=ffffff><td>> Текст3</td><td><b>10.70</td></tr>
<tr bgcolor=EEF4FA><td>> Текст4</td><td><b><font color=EEF4FA>_</font>9.15</td></tr>
"""
print re.findall(r"<tr .+Текст\d.+>(\d{1,2}\.\d{2})<.+</tr>", subject)
bw
> Но все-таки хотелось бы понять, можно ли это сделать с помощью re.
Можно, но не нужно.
Если это не xhtml или он не валидный смотри на html5lib и/или BeautifulSoup. Если это валидный xml (xhtml) смотри на стандартный xml и всё что в нём есть. Так же может быть полезным ElementTree, он входит в Python 2.5 (xml.etree) и стоит посмотреть на дополнения стандартного xml PyXML (python-xml). Существует еще несколько пакетов для работы с xml.

..bw
Positive
Ух ты, спасибо!

Вижу, что мне еще учиться и учиться :)
Positive
bw
и вам спасибо, просто для меня важно понять regexp'ы
но раз так советуете воспользоваться парсерами HTML - обязательно посмотрю
bw
> просто для меня важно понять regexp'ы
Регулярные выражения в этой задаче, просто не практичны. И если кто-то решит дорабатывать ваш код (это можете оказаться и вы, через 3-6 месяцев), он просто утонет в них. А возвращаться к ним придется, так как современный HTML куда сложнее пару треугольных скобок. Сложнее не потому что он так крут, а потому что никто не соблюдает стандарты. В каких-то локальных задачах (быстрое извлечение контента со страницы) регулярки могут выигрывать у валидирующих парверов, но это палка о двух концах, полученный контент может оказаться некорректным (битым) или вообще в половине случаев не тем.

..bw
Ferroman
# -*- coding: utf-8 -*-
import re
st = u'<tr bgcolor=ffffff><td> Текст1</td><td><b>12.22</td></tr><tr bgcolor=EEF4FA><td> Текст2</td><td><b>12.10</td></tr><tr bgcolor=ffffff><td> Текст3</td><td><b>10.70</td></tr><tr bgcolor=EEF4FA><td> Текст4</td><td><b><font color=EEF4FA>_</font>9.15</td></tr>'
pattern1 = re.compile(u'(?<=Текст4</td><td><b>)(<font color=EEF4FA>_</font>)?(\d{1,2}\.\d{2})')
print pattern1.findall(st)[0][1]
Yurietc
bw
Регулярные выражения в этой задаче, просто не практичны. И если кто-то решит дорабатывать ваш код (это можете оказаться и вы, через 3-6 месяцев), он просто утонет в них. А возвращаться к ним придется, так как современный HTML куда сложнее пару треугольных скобок. Сложнее не потому что он так крут, а потому что никто не соблюдает стандарты. В каких-то локальных задачах (быстрое извлечение контента со страницы) регулярки могут выигрывать у валидирующих парверов, но это палка о двух концах, полученный контент может оказаться некорректным (битым) или вообще в половине случаев не тем.
В принципе я согласен, но все же посоветовал бы комбинировать методы. Регексп + BeautifulSoup или другая библиотека.
В любом случае при обработке текстов без регекспов грустно.
Мой вариант решения исходной задачи :
>>> s='''<tr bgcolor=ffffff><td>> Текст1</td><td><b>12.22</td></tr><tr bgcolor=EEF4FA><td>> Текст2</td><td><b>12.10</td></tr><tr bgcolor=ffffff><td>> Текст3</td><td><b>10.70</td></tr><tr bgcolor=EEF4FA><td>> Текст4</td><td><b><font color=EEF4FA>_</font>9.15</td></tr>'''
>>> o=re.compile('Текст(\d+)')
>>> o.findall(s)
['1', '2', '3', '4']
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB