в следующих примерах, я пытаюсь создать регулярное выражение, чтобы найти последнюю группу из 1 или более последовательных цифр в строке.
насколько я знаю, в python3, re.search() проходит через строку поиска, которая пытается совместить слева направо.
объясняет ли это поведение в приведенных ниже примерах? В частности, это причина, по которой ". *?" необходимо перед блоком захвата (когда он привязан к фронту, как в первых двух примерах), чтобы блок захвата мог записывать обе цифры, тогда как '?' необязательно, когда регулярное выражение привязано к концу строки (как в двух последних примерах?)
Python 3.1.2 (release31-maint, Sep 17 2010, 20:27:33)
>>> import re
>>> a = "hi there in the morning {23)"
>>> R = re.compile('^.*(\d+)', re.IGNORECASE); print(R.search(a).group(1))
3
>>> R = re.compile('^.*?(\d+)', re.IGNORECASE); print(R.search(a).group(1))
23
>>> R = re.compile('(\d+).*$', re.IGNORECASE); print(R.search(a).group(1))
23
>>> R = re.compile('(\d+).*?$', re.IGNORECASE); print(R.search(a).group(1))
23
^.*(\d+)
- Матч с начала. .*
будет соответствовать всему пути до конца строки, а затем \d+
сделает .*
backtrack (отменяет предыдущие совпадения) как можно меньше, поэтому \d+
будет соответствовать только последней цифре.^.*?(\d+)
- Матч с начала. .*?
сначала ничего не соответствует. \d+
провалится позже (если первый символ не является цифрой), сделайте .*?
backtrack и сопоставьте дополнительные символы, пока не найдет первую цифру, а затем +
будет соответствовать всем цифрам после нее. для abc123edf567
шаблон будет соответствовать 123
, первый набор цифр.(\d+).*$
- \d+
будет соответствовать первой группе цифр. .*$
всегда будет успешным и будет соответствовать до конца.(\d+).*?$
- Это одно и то же (хотя, возможно, и медленнее). \d+
будет соответствовать первой группе цифр. .*?$
сначала ничего не будет соответствовать, но затем будет соответствовать все больше символов, пока не достигнет $
. Имейте в виду, что *?
ленив влево, но это не значит, что движок будет принимать как можно меньше символов справа.То, что вы, вероятно, ищете, это (\d+)\D*$
- сопоставить набор символов, за которыми следуют символы non- и конец строки. Это вернет последний набор цифр.
Смотрите также: regular- expressions.info - Лень вместо жадности
Сам по себе *
жадный; он будет соответствовать столько, сколько он может, позволяя регулярному выражению в целом соответствовать, поэтому .*
будет сожрать все, кроме одной цифры, необходимой для соответствия \d+
.
*?
использует non- жадное соответствие, поэтому соответствуют только цифры non-.
Как сказал Wooble, * жадный, поэтому в вашей строке для первого примера самое жадное соответствие для. *?
будет hi there in the morning {2
, так как \d+
будет true только с одним значением, 3
.