Разница в регулярном выражении между Python и Rubular?

В Rubular я создал регулярное выражение:

(Prerequisite|Recommended): (\w|-| )*

Соответствует выделенному жирным шрифтом:

Рекомендуется: хороший уровень владения компьютером и некоторыми видами искусства.

Лето. 2 кредита. Необходимое условие: репутация перед первокурсником или разрешение инструктора. Кредит не может быть применен к диплому инженера. Только оценки S-U.

Вот использование регулярного выражения в Python:

note_re = re.compile(r'(Prerequisite|Recommended): (\w|-| )*', re.IGNORECASE)

def prereqs_of_note(note):
    match = note_re.match(note)
    if not match:
        return None
    return match.group(0) 

К сожалению, код возвращает None вместо совпадения:

>>> import prereqs

>>> result  = prereqs.prereqs_of_note("Summer. 2 credits. Prerequisite: pre-fres
hman standing or permission of instructor. Credit may not be applied toward engi
neering degree. S-U grades only.")

>>> print result
None

Что я здесь делаю неправильно?

ОБНОВЛЕНИЕ: нужно ли мне re.search() вместо re.match()?


person Nick Heiner    schedule 09.05.2010    source источник
comment
pythex.org говорит, что регулярное выражение соответствует этой строке даже при использовании механизма Python, поэтому проблема заключается в том, как вы используете регулярное выражение (я не знаю Python)   -  person Gareth    schedule 10.05.2010
comment
Кроме того, лично я бы обновил ваше регулярное выражение до (Prerequisite|Recommended): ([\w -]*), чтобы вы могли лучше зафиксировать остальную часть совпадения. (См. rubular.com/r/5v7u66vc1M)   -  person Gareth    schedule 10.05.2010


Ответы (1)


Вы хотите использовать re.search(), потому что он сканирует строку. Вам не нужен re.match(), потому что он пытается применить шаблон в начале строки.

>>> import re
>>> s = """Summer. 2 credits. Prerequisite: pre-freshman standing or permission of instructor. Credit may not be applied toward engineering degree. S-U grades only."""
>>> note_re = re.compile(r'(Prerequisite|Recommended): ([\w -]*)', re.IGNORECASE)
>>> note_re.search(s).groups()
('Prerequisite', 'pre-freshman standing or permission of instructor')

Кроме того, если вы хотите, чтобы после первого периода, следующего за словом «инструктор», вам нужно было добавить буквальное «.». в свой шаблон:

>>> re.search(r'(Prerequisite|Recommended): ([\w -\.]*)', s, re.IGNORECASE).groups()
('Prerequisite', 'pre-freshman standing or permission of instructor. Credit may not be applied toward engineering degree. S-U grades only.')

Я бы посоветовал вам сделать свой шаблон более жадным и совпадать с остальной частью строки, если только это не совсем то, что вы хотите, хотя кажется, что вы этого хотите.

>>> re.search(r'(Prerequisite|Recommended): (.*)', s, re.IGNORECASE).groups()
('Prerequisite', 'pre-freshman standing or permission of instructor. Credit may not be applied toward engineering degree. S-U grades only.')

Предыдущий шаблон с добавлением литерала '.' возвращает то же самое, что и .* для этого примера.

person jathanism    schedule 09.05.2010
comment
... или, может быть, (.*?\.), чтобы соответствовать только до первого периода. - person Alan Moore; 10.05.2010