#python #regex #re
Вопрос:
Я ищу такие слова, как «один год», «два года», «2-3 года» или «3-4 года» в длинной строке. Я пытался сделать это с помощью регулярных выражений. Но я не уверен, что понял это, когда участвуют группы.
Давайте посмотрим, что я имею в виду:
import re
text = 'one year, honey 2-5 year, dressed six, ten'
pattern = r'(one|two|three|four|five|six|seven|eight|nine|ten|
eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|
eighteen|nineteen|twenty|[0-9] [- ]*[0-9]*)[ ]*year?'
re.findall(pattern, text) # ['one', '2-5']
Моя проблема в том, что я хочу ['one year', '2-5 years']
. Я не знаю, как это сделать. Если бы я забыл о цифрах в словах:
pattern = r'[0-9] [- ]*[0-9]*[ ]*year?'
re.findall(pattern, text) # ['2-5 years']
Почему я попал years
во второй, а не в первый? Как я могу изменить его, чтобы получить годы в первом?
Заранее спасибо,
Комментарии:
1.
[0-9] [- ]*[0-9]*
должен быть первым элементом в списке чередования2. Почему после буквы » р » стоит вопросительный знак? Разве ты не имеешь в виду
years?
вместо этого?
Ответ №1:
Сначала вам нужно исправить шаблон, чтобы он соответствовал числам. Вот пример:
>>> pattern = r'''(?x)b(?:[0-9] (?:[- ]*[0-9] )?|one|two|three|four|five|six|seven|eight|nine|ten
|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)
[ ]*years?b'''
>>> re.findall(pattern, text)
['one year', '2-5 year']
Смотрите демонстрационную версию Python и демонстрационную версию регулярных выражений.
Подробные сведения
(?x)
—re.X
/re.VERBOSE
встроенный модификаторb
— граница слов(?:
— начало группы без захвата[0-9] (?:[- ]*[0-9] )?
— одна или несколько цифр, за которыми следуют ноль или несколько пробелов, или-
, а затем одна или несколько цифр|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty
— одно из слов в списке чередования
)
— конец группы без захвата[ ]*
— ноль или большеyears?
—year
илиyears
b
— граница слов.
Комментарии:
1. @Xbel Также соответствует «Я купил телефон много лет назад».
Ответ №2:
В вашем регулярном выражении year?
должно быть years?
потому, что это конечная буква «s», которая является необязательной, а не «r». Вам также необходимо использовать так называемые группы без захвата (?: ... )
, чтобы получить строку, соответствующую всему регулярному выражению; в противном случае вы получите только строки, соответствующие заключенным в скобки подвыражениям.
Для улучшения читаемости также рекомендуется разделить длинное регулярное выражение на подвыражения и дать им значимые имена. Попробуйте это:
import re
text = 'one year, honey 2-5 year, dressed six, ten'
numberWordsRe = r'one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty'
numberOrIntervalRe=r'd (?:s*-s*d )'
pattern = r'b(?:' numberWordsRe r'|' numberOrIntervalRe r')s years?b'
print re.findall(pattern, text)
Комментарии:
1. Это уточняющие комментарии. Танков много.