2015-05-25 4 views
0

Как указать, какая группа возвращаемых данных регулярного выражения я хочу напечатать. При использовании функции re.search я бы просто использовать:Python 3.4: группировка списка регулярных выражений

print(tickers.group(2)) 

Модуля FindAll не позволяет мне использовать .group (2), а перебор возвращаемого списка.

url = 'https://en.wikipedia.org/wiki/List_of_S%26P_500_companies' 

req = urllib.request.Request(url) 
resp = urllib.request.urlopen(req) 
respData = resp.read() 
dRespData = respData.decode('utf-8') 

findTicker = re.compile(r'(">)([A-Z]{1,4})(</a></td>)') 

tickers = re.findall(findTicker, dRespData) 

print(tickers) 

Результат

[('">', 'MMM', '</a></td>'), ('">', 'ABT', '</a></td>'), ('">', 'ABBV', '</a></td>')....... 

Мне нужно просто вернуть 'МММ', 'ABT', 'ABBV'.

+0

Можете ли вы объяснить, почему вы используете регулярные выражения для HTML? – Tomalak

+0

Я хочу разобрать википедию для списка тиков акций sp500. Я использовал простую функцию разделения, и 120 тикеров были исключены из-за незначительных различий кода. Есть ли лучший способ предложить вам? –

+0

Да, это называется парсером HTML. – Tomalak

ответ

0

Используйте анализатор. Регулярные выражения неспособны работать с HTML.

pquery хорош, например:

from pyquery import PyQuery as pq 

doc = pq(url='https://en.wikipedia.org/wiki/List_of_S%26P_500_companies') 

for heading in doc(".mw-headline:contains('S&P 500 Component Stocks')").parent("h2"): 
    rows = pq(heading).next("table tr") 
    for row in rows: 
     tds = pq(row).find("td") 
     print tds.eq(0).text() 

Теперь было так трудно? Представьте, что структура страницы Википедии меняется, или требования становятся более сложными. Решение на основе парсера останется поддерживаемым, решение на основе регулярных выражений будет ухудшаться в непонятном, запутанном от ошибок беспорядке.

+1

Это решение не соответствует требованиям OP. OP собирает содержимое '', которое соответствует шаблону '[A-Z] {1,4}'. –

+0

Вы оба предоставили мне полезную информацию :-) –

0

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

findTicker = re.compile(r'(?<=">)([A-Z]{1,4})(?=</a></td>)') 

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

Beautiful Soup путь (для регулярных выражений агностик людей):

from bs4 import BeautifulSoup 
s = 'YOUR_HTML' 
soup = BeautifulSoup(s) 
for a in soup.findAll('a'): 
     if re.match(r'[A-Z]{1,4}$', a.contents): 
       print a.contents 
+0

Красивая! Большое спасибо! –

+0

Уверен, вы также можете сделать это с помощью прекрасного супа, но вам нужно добавить ссылку на внешнюю библиотеку. Я видел сообщения SO, в которых люди жаловались на размер BS для Python 3.x. –

+0

Сокращенное значение для рекомендации regex для проблемы с HTML. – Tomalak

Смежные вопросы