3.5 Флагове при компилация

Флаговете при компилация ви дават възможност да променяте някои аспекти на начина на работа на регулярните изрази. Флаговете са достъпни в модула re под две имена - едно дълго име като IGNORECASE, и една кратка, еднобуквена форма като I. (Ако сте запознати с модификаторите на образци в Perl, еднобуквените форми в Питон използват същите букви; кратката форма на re.VERBOSE е re.X.) Могат да бъдат указвани няколко флага чрез побитовото им ИЛИ; например, re.I | re.M установява едновременно флаговете I и M.

Ето една таблица на възможните флагове, последвана от по-подробно разяснение за всеки от тях.

Флаг  Значение 
DOTALL, S Прави така, че . да пасва с всеки символ, дори със символа за нов ред.
IGNORECASE, I При съпоставянето се пренебрегва разликата между малки и големи букви.
LOCALE, L Съпоставя, съобразявайки се с текущия локал.
MULTILINE, M Многоредови съпоставяния, оказва влияние върху ^ и $.
VERBOSE, X Позволява многословните РИ, които могат да се съставят по-ясно и разбираемо.

I
IGNORECASE
Съпоставянията стават нечувствителни към разликата между малки и големи букви; класовете от символи и низовете ще пасват, пренебрегвайки разликата между горен и долен регистър. Например, [A-Z] ще пасва и с малките букви, а Spam ще пасва със "Spam", "spam", или "spAM".1 При това не се взима предвид текущия локал. Това означава, че дори при правилно локализирана система и вдигнат флаг IGNORECASE, все още се разграничават малките и големите букви при работа с български език.

>>> r = re.compile('Пещера', re.IGNORECASE)
>>> print r.match('ПЕЩЕРА')
None

Това ограничение е преодоляно едва при Питон 2.0, където се поддържат символни низове Unicode и модулът re предоставя допълнителен флаг за компилиране на регулярни изрази, които да работят според Unicode:

>>> r = re.compile('Пещера', re.IGNORECASE | re.UNICODE)
>>> print r.match('ПЕЩЕРА')
<SRE_Match object at 0x8085a10>

Обърнете внимание на допълнителният флаг UNICODE, който не е разгледан тук, но е достъпен в модула re от версиите на Питон 2.0 и следващите.

L
LOCALE
Поставя \w, \W, \b, и \B под зависимост от текущия локал.

Локалите са свойство на библиотеката на C, предназначено да улесни писането на програми, които взимат предвид особеностите на езика. Например, ако обработвате български текст, ще искате да пишете \w+ за да пасвате думи, но \w пасва само с класа от символи [A-Za-z]; той няма да пасва с "ю" или "ж". Ако системата ви е настроена правилно и е избран български локал, тогава определени функции на C ще кажат на програмата, че "ю" трябва да се счита за буква. Вдигането на флага LOCALE при компилирането на един регулярен израз ще накара получения компилиран обект да използва тези функции на C за \w. Така ще става по-бавно, но все пак се дава възможност на \w+ да пасва и с български думи, както бихте очаквали.

M
MULTILINE
Обикновено ^ пасва само с началото на символния низ, а $ пасва с края му и точно преди новия ред (ако има такъв) в края на символния низ. Когато този флаг е вдигнат, ^ пасва освен с началото на символния низ, така и в началото на всеки ред от низа, веднага след символ за нов ред. По подобен начин, метасимволът $ пасва хем с края на символния низ, хем с края на всеки ред (точно преди всеки символ за нов ред).

S
DOTALL
Прави така, че специалният символ "." пасва с всеки символ изобщо, дори и със символ нов ред. Без този флаг, "." ще пасва с всичко, с изключение на символа за нов ред.

X
VERBOSE
Този флаг ви позволява да пишете по-четливи регулярни изрази, като ви дава по-голяма гъвкавост при форматирането им. Когато този флаг е вдигнат, празното пространство в рамките на символния низ на РИ се пренебрегва, с изключение случая когато то е в клас от символи или е предходено от неизбегната обратно наклонена черта. Това ви дава възможност по-ясно да организирате и подравнявате този РИ. Това също ви дава възможност да слагате коментари в РИ; коментарите се отбелязват с "#", който не е нито в клас от символи, нито се предхожда от неизбегната обратно наклонена черта. Коментарите просто се пренебрегват.

Ето един пример, където един РИ използва re.VERBOSE. Виждате ли колко е по-лесен за четене?

charref = re.compile(r"""
 &\#          # Започва указател за число
 (?P<char>      
   [0-9]+[^0-9]      # Десетична форма
   | 0[0-7]+[^0-7]   # Осмична форма
   | x[0-9a-fA-F]+[^0-9a-fA-F] # Шестнадесетична форма
 )
""", re.VERBOSE)
Без многословната настройка, този РИ би изглеждал така:
charref = re.compile("&#(?P<char>[0-9]+[^0-9]"
                     "|0[0-7]+[^0-7]"
                     "|x[0-9a-fA-F]+[^0-9a-fA-F])")
За да бъде разбит РИ на по-малки части, в горният пример е използвано автоматичното свързване на символни низове в Питон. Но дори и така той е по-неразбираем отколкото варианта, използващ re.VERBOSE.



Footnotes

....1
"Spam", "spam", "spam", "spam", "spam", ...