Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 4, 2008 12:00:06

Positive
От:
Зарегистрирован: 2008-12-04
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

Здравствуйте.

Есть некий кусок 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?



Офлайн

#2 Дек. 4, 2008 12:27:56

Dimka665
От:
Зарегистрирован: 2008-09-19
Сообщения: 177
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

может стоит использовать модуль HTMLParser?



Офлайн

#3 Дек. 4, 2008 12:50:51

Positive
От:
Зарегистрирован: 2008-12-04
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

Dimka665
может стоит использовать модуль HTMLParser?
Спасибо, я посмотрю, что можно с ним сделать.

Но все-таки хотелось бы понять, можно ли это сделать с помощью re.



Офлайн

#4 Дек. 4, 2008 14:32:18

shiza
От:
Зарегистрирован: 2007-07-03
Сообщения: 1073
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

как-нибудь так? =)

#!/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)



Отредактировано (Дек. 4, 2008 14:35:01)

Офлайн

#5 Дек. 4, 2008 14:37:02

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Правильное регулярное выражение для HTML-кода

> Но все-таки хотелось бы понять, можно ли это сделать с помощью re.
Можно, но не нужно.
Если это не xhtml или он не валидный смотри на html5lib и/или BeautifulSoup. Если это валидный xml (xhtml) смотри на стандартный xml и всё что в нём есть. Так же может быть полезным ElementTree, он входит в Python 2.5 (xml.etree) и стоит посмотреть на дополнения стандартного xml PyXML (python-xml). Существует еще несколько пакетов для работы с xml.

..bw



Отредактировано (Дек. 4, 2008 14:39:13)

Офлайн

#6 Дек. 4, 2008 14:38:33

Positive
От:
Зарегистрирован: 2008-12-04
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

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

Вижу, что мне еще учиться и учиться :)



Офлайн

#7 Дек. 4, 2008 14:40:48

Positive
От:
Зарегистрирован: 2008-12-04
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

bw
и вам спасибо, просто для меня важно понять regexp'ы
но раз так советуете воспользоваться парсерами HTML - обязательно посмотрю



Офлайн

#8 Дек. 4, 2008 14:48:24

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

Правильное регулярное выражение для HTML-кода

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

..bw



Офлайн

#9 Дек. 4, 2008 14:51:22

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

# -*- 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]

Отредактировано (Дек. 4, 2008 14:52:29)

Офлайн

#10 Дек. 10, 2008 14:35:29

Yurietc
От:
Зарегистрирован: 2007-07-18
Сообщения: 112
Репутация: +  0  -
Профиль   Отправить e-mail  

Правильное регулярное выражение для HTML-кода

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']



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version