2013-09-02 4 views
1

Это код, который я использую из учебника Christophers Reeves о том, как он соскабливает его третье видео по теме на youtube.Python Regex Compile 2.7.5

import urllib 
import re 

symbolslist = ["aapl","spy","goog","nflx"] 

i=0 
while i<len(symbolslist): 
    url = "http://finance.yahoo.com/q?s=" +symbolslist[i] +"&q1=1" 
    htmlfile = urllib.urlopen(url) 
    htmltext = htmlfile.read() 
    regex = '<span id="yfs_l84_'+symbolslist[i] +'">(.?+)</span>' 
    pattern = re.compile(regex) 
    price = re.findall(pattern,htmltext) 
    print "The price of", symbolslist[i]," is", price 
    i+=1 

Я получаю следующее сообщение об ошибке, когда я запускаю этот код в Python 2.7.5

Traceback <most recent call last>: 
File "fundamentalism)stocks.py, line 12, in <module> 
pattern = re.compile(regex) 
File "C:\Python27\lib\re.py", line 190, in compile 
return _compile(pattern, flags) 
File "C:\Python27\lib\re.py, line 242, in compile 
raise error, v # invalid expression 
sre_constant.error: multiple repeat 

Я не знаю, если проблема с тем, как моя библиотека, установлена, моя версия питон или что. Я ценю вашу помощь.

ответ

3

Проблема заключается в использовании нескольких повторяющихся символов: + и ?.

Возможно, non-greedy соответствие предназначалось вместо: (.+?):

'*', '+' и '?' отборочные все жадные; они соответствуют как можно большему количеству текста. Иногда такое поведение нежелательно; если RE <.*> соответствует «<H1>title</H1>», он будет соответствовать всей строке, а не только «<H1>». Добавление «?» после того, как квалификатор заставляет его выполнять матч не-жадным или минимальным образом; как можно меньше символов. Использование .*? в предыдущем выражении будет соответствовать только '<H1>' ..

+0

Спасибо за помощь. В этом есть смысл. Где я могу узнать об этом больше? –

+1

Ну, [здесь] (http://docs.python.org/2/howto/regex.html), [здесь] (http://www.youtube.com/watch?v=FH-ZFOZxjMs), [ здесь] (http://stackoverflow.com/questions/4273987/python-re-sub-use-non-greedy-mode-with-end-of-string-it-comes-greedy) и т. д. :) – alecxe

0

В качестве регулярного выражения измените строку

regex = '<span id="yfs_l84_'+symbolslist[i] +'">(.?+)</span>' 

быть

regex = '<span id="yfs_l84_'+symbolslist[i] +'">(.+?)</span>' 

... обратите внимание, что, не входящих в -greedy синтаксис классификатора был изменен на (. +?)

0

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

for symbol in symbolslist: 
    url = "http://finance.yahoo.com/q?s=%s&q1=1" % symbol 
    htmlfile = urllib.urlopen(url) 
    htmltext = htmlfile.read() 
    regex = '<span id="yfs_l84_%s">(.?+)</span>' % symbol 
    price = re.findall(regex, htmltext)[0] 
    print "The price of", symbol," is", price 
  • Стандартный Python идиома для перебора всех значений в списке, чтобы не выбрать их по индексу.
  • «Строчная интерполяция» намного проще управлять, чем конкатенация строк, особенно если вы добавляете несколько значений в микс (например, возможно, вы хотите указать значение q1 в более поздней версии).
  • re.findall берет строку в качестве первого аргумента. Явно компилируя шаблон, а затем бросая его в следующий цикл, вы ничего не получаете.
  • re.findall возвращает список, и вам нужен только первый элемент.
Смежные вопросы