различное поведение при использовании re.finditer и re.match - PullRequest
1 голос
/ 10 января 2011

Я работаю над регулярным выражением, чтобы собрать некоторые значения со страницы через некоторый скрипт.Я использую re.match в условии, но он возвращает false, но если я использую finditer, он возвращает true, и тело условия выполняется.Я протестировал это регулярное выражение в своем собственном тестере, и он работает там, но не в сценарии.Вот пример сценария.

result = []
RE_Add0 = re.compile("\d{5}(?:(?:-| |)\d{4})?", re.IGNORECASE)
each = ''Expiration Date:\n05/31/1996\nBusiness Address: 23901 CALABASAS ROAD #2000 CALABASAS, CA 91302\n'
if RE_Add0.match(each):
    result0 = RE_Add0.match(each).group(0)
    print result0
    if len(result0) < 100:
        result.append(result0)
    else:
        print 'Address ignore'
else:
    None

Ответы [ 3 ]

3 голосов
/ 10 января 2011

re.finditer() возвращает объект итератора, даже если совпадений нет (поэтому if RE_Add0.finditer(each) всегда будет возвращать True).Вы должны фактически выполнить итерацию по объекту, чтобы увидеть, есть ли реальные совпадения.

Тогда re.match() соответствует только в начале строки, а не в любом месте строки, как re.search() или re.finditer() do.

В-третьих, это регулярное выражение может быть записано как r"\d{5}(?:[ -]?\d{4})".

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

1 голос
/ 10 января 2011

re.match соответствует началу строки только один раз.re.finditer аналогичен re.search в этом отношении, то есть он совпадает итеративно.Сравните:

>>> re.match('a', 'abc')
<_sre.SRE_Match object at 0x01057AA0>
>>> re.match('b', 'abc')
>>> re.finditer('a', 'abc')
<callable_iterator object at 0x0106AD30>
>>> re.finditer('b', 'abc')
<callable_iterator object at 0x0106EA10>

ETA: Поскольку вы упоминаете page , я могу только предположить, что вы говорите о разборе html, если это так, используйте BeautifulSoup или аналогичныйHTML-парсер.Не используйте регулярные выражения.

0 голосов
/ 10 января 2011

Попробуйте это:

import re

postalCode = re.compile(r'((\d{5})([ -])?(\d{4})?(\s*))$')
primaryGroup = lambda x: x[1]

sampleStr = """
    Expiration Date:
    05/31/1996
    Business Address: 23901 CALABASAS ROAD #2000 CALABASAS, CA 91302  
"""
result = []

matches = list(re.findall(postalCode, sampleStr))
if matches:
    for n,match in enumerate(matches): 
        pc = primaryGroup(match)
        print pc
        result.append(pc)
else:
    print "No postal code found in this string"

Возвращает '12345' для любого из

12345\n
12345  \n
12345 6789\n
12345 6789    \n
12345 \n
12345     \n
12345-6789\n
12345-6789    \n
12345-\n
12345-    \n
123456789\n
123456789    \n
12345\n
12345    \n

У меня совпадение только в конце строки, потому что в противном случае оно также совпадало'23901' (с адреса улицы) в вашем примере.

...