4.2 Групиране

Много често се нуждаете от повече информация, отколкото просто да определите дали този РИ пасва или не. Регулярните изрази също често се използват и за разрязване на символни низове чрез съставяне на РИ, композиран от няколко подгрупи, които пасват с различни интересуващи ви компоненти. Например, един ред от заглавна част според RFC-822 се разделя на заглавно име и стойност, разделени едно от друго чрез ":". Това може да бъде обработено чрез съставянето на регулярен израз, който пасва с целия заглавен ред, и съдържа една група, пасваща със заглавното име, и друга група, пасваща със стойността му.

Групите се отбелязват с метасимволите "(" и ")". "(" и ")" имат съвсем същото значение като в математическтие изрази -- те групират изразите, съдържащи се в тях. Например, чрез квалификатор за повторение като *, +, ?, или {m,n} можете да повторите съдържанието на дадена група. Например (ab)* ще пасне с нула или повече повторения на "ab".

>>> p = re.compile('(ab)*')
>>> print p.match('ababababab').span()
(0, 10)

Също така, групите, означени с "(", ")" прихващат началния и крайния индекс на текста, с който си пасват. Индексите могат да бъдат получени като се подаде аргумент на group(), start(), end() и span(). (По-късно ще видим как се изразяват групи, които не прихващат диапазона от текста, с който си пасват.) Групите са номерирани, започвайки от 0. Винаги има група 0; тя е целият РИ. По подразбиране всички методи работят с група 0.

>>> p = re.compile('(a)b')
>>> m = p.match('ab')
>>> m.group()
'ab'
>>> m.group(0)
'ab'

Подгрупите са номерирани от ляво на дясно, започвайки от 1. Групите могат да бъдат влагани една в друга. За да определите номера на дадена група, просто пребройте отворените скоби, тръгвайки от ляво на дясно.

>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'

На метода group() могат едновременно да се подадат няколко номера на групи. В такъв случай, той ще върне комплект, съдържащ съответните стойности за тези групи.

  
>>> m.group(2,1,2)
('b', 'abc', 'b')

Методът groups() връща комплект, съдържащ символните низове за всички подгрупи от 1 до колкото са според случая.

  
>>> m.groups()
('abc', 'b')

Отпратките ви дават възможност да указвате, че съдържанието на една предишна група трябва отново да се намира на текущата позиция на символния низ. Например, \1 ще успее ако на текущата позиция се намира точното съдържание на група 1, а в противен случай ще пропадне. Помнете, че за да се позволи включването на произволни знаци в символните низове на Питон, там също се използва обратно наклонена черта, последвана от числа. Така че се уверете, че използвате суров символен низ, когато поставяте отпратки в даден РИ.

Например, следващият РИ открива повторени думи в символен низ:

>>> p = re.compile(r'(\b\w+)\s+\1')
>>> p.search('Paris in the the spring').group()
'the the'

Отпратките като тази не са чак толкова полезни, когато просто се търси из символен низ -- съществуват много малко текстови формати, които повтарят данните по този начин. Обаче скоро ще се убедите, че те са много полезни при извършването на замествания в символните низове.