събота, 17 януари 2009 г.

Регулярни изрази в Python


„ Програмиране с Python“, ФМИ

28.02.2007г.

Идеята

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

Прост пример

  • на pam съответстват spam и pamela
  • на h(ot|ound) dog съответстват hot dog и hound dog
  • на fn\d+ съответстват fn1, fn44444, fn420169 и т.н.
  • на .at съответстват hat, cat, rat и т.н.
  • на [a-zA-Z0-9._]+@[a-aA-Z0-9._]+\.[a-z]+ съответстват повечете email адреси

В детайли

  • Регулярните изрази представляват текстови низове
  • Буквите и цифрите съответстват на себе си
  • Точката съответства на всеки символ, без новия ред
  • \d съответства на цифра
  • \w съответства на буква
  • \s съответства на бяло пространство
  • \D, \W и \S са инверсии на съответните символи

В детайли (2)

  • \d\d\d\d\d\d\d съответства на ЕГН
  • \w\w\w\d\w\w\d\d съответства на три букви, цифра, две букви и после две цифри (например ani4ka92)
  • fn\d\d\d\d\d съответства на част от факултетните номера
  • M\w\w\w\w\sT\w\w\sP\w\w\w\w\w би хванало Mityo The Python
  • s..m съответства на spam и sram

В Python

В Python се ползва модулът re

import re

>>> import re
>>> re.search('spam', 'gmail')
>>> re.search('s..m', 'spam')
<_sre.sre_match>
>>> re.search('\\d\\d', 'asnwer: 42')
<_sre.sre_match>

Още детайли

  • Операторът | в регулярните изрази означава това отляво или това отдясно
  • (c|h)at намира cat и hat
  • ^ съвпада с началото на низа. ^oo ще намери oop, но не и foo.
  • $ съвпада с края на низа. ar$ ще намери bar, но не и argh.

Повторения

  • ? означава, че да го има 0 или 1 пъти
  • + означава, че нещо може да го има един или повече пъти
  • * означава, че нещо може да го има нула или много пъти
  • {x, y} означава, че нещо може да го има от x до y пъти
Примери:
\d{8}

fn\d+
\d{1,2}\.\d{1,2}.\d{4}
route\d*

Класове

  • Класовете съответстват на някакво множество от символи.
  • Бележат се с [].
  • [chr]at съответства на cat, hat и rat.
  • Могат да включват и последователности от символи - [a-z0-8] съответства на малка буква или цифра, без 9
  • Ако започва с ^, класът се интерпретира като отрицание на символите вътре - [^A-Z] съответства на нещо, което не е голяма буква

Област

Върнатия от search обект има методи start, end и span.



>>> import re
>>> text = 'Bla bla bla mityo blabla bla'
>>> match = re.search(r'mityo', text)
>>> match.span()
(12, 17)
>>> match.start(), match.end()
12, 17
>>> text[match.start(), match.end()]
'mityo'

Групи

Всички изрази оградени със скоби се запазват в обекта върнат от re.search. Те се наричат групи



>>> import re
>>> match = re.search(r'\w+ (\w+), fn(\d+)',
'Nickolay Bachiiski, fn43600')
>>> match.group(1)
'Bachiiski'
>>> match.group(2)
'43600'

Субституции

Всички изрази оградени със скоби се запазват в обекта върнат от re.search. Те се наричат групи



>>> import re
>>> re.sub(r':(.*)!', r'!\1?', "I'm a :very big! hacker!")
"I'm a !very big hacker?"

Алчни "квантификатори"

+, * и {x,y} намират максималния брой символи, които могат. Това се нарича "алчно поведение" (greedy). Ако искате да намирате минималния брой, добавете едно ? към края



>>> import re
>>> re.sub(r'(.*)', r'\1',
'My name is Mityo the Python')
'My name is Mityo the Python'

>>> re.sub(r'(.*?)', r'\1',
'My name is Mityo the Python')
'My name is Mityo the Python'

Няма коментари:

Публикуване на коментар