Да бисмо извршили обраду регуларних израза у Питхон-у, користимо модул ре из стандардне библиотеке. Омогућава вам да извучете, замените и поделите низове користећи обрасце регуларног израза.
- re — Regular expression operations — Python 3.10.0 Documentation
- Regular Expression HOWTO — Python 3.10.0 Documentation
У овом одељку ћемо прво објаснити функције и методе ре модула.
- Састављање образаца регуларних израза:
compile()
- подударање објекта
- Проверите да ли се почетак стринга поклапа, издвојите:
match()
- Проверите подударања која нису ограничена на почетак:
search()
- Проверите да ли се цео низ подудара:
fullmatch()
- Добијте листу свих одговарајућих делова:
findall()
- Набавите све одговарајуће делове као итератор:
finditer()
- Замените одговарајући део:
sub()
,subn()
- Подела стрингова са обрасцима регуларног израза:
split()
Након тога ћу објаснити мета знакове (специјалне знакове) и посебне секвенце регуларних израза који се могу користити у ре модулу. У основи, то је стандардна синтакса регуларног израза, али будите опрезни при постављању заставица (нарочито ре.АСЦИИ).
- Метазнакови регуларног израза, специјалне секвенце и упозорења у Питхон-у
- Постављање заставе
- Ограничено на АСЦИИ знакове:
re.ASCII
- Не разликују:
re.IGNORECASE
- Ускладите почетак и крај сваког реда:
re.MULTILINE
- Наведите више заставица
- Ограничено на АСЦИИ знакове:
- Похлепне и непохлепне утакмице
- Саставите образац регуларног израза: цомпиле()
- подударање објекта
- Проверите да ли се почетак стринга поклапа, издвојите: матцх()
- Проверите подударања која нису ограничена на почетак, издвојите: сеарцх()
- Проверите да ли се цео низ подудара: фуллматцх()
- Добијте листу свих одговарајућих делова: финдалл()
- Узми све одговарајуће делове као итератор: финдитер()
- Замените одговарајуће делове: суб(), субн()
- Подела стрингова са обрасцима регуларног израза: сплит()
- Метазнакови регуларног израза, специјалне секвенце и упозорења у Питхон-у
- Постављање заставе
- Похлепне и непохлепне утакмице
Саставите образац регуларног израза: цомпиле()
Постоје два начина да се изврши обрада регуларног израза у модулу ре.
Покрени са функцијом
Прва је функција.re.match()
,re.sub()
Функције попут ових су доступне за извођење екстракције, замене и других процеса користећи обрасце регуларног израза.
Детаљи функција биће описани касније, али у свима њима први аргумент је стринг шаблона регуларног израза, затим низ који треба обрадити и тако даље. На пример, у ре.суб(), који врши замену, други аргумент је низ замене, а трећи аргумент је стринг који треба да се обради.
import re
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.match(r'([a-z]+)@([a-z]+)\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
result = re.sub(r'([a-z]+)@([a-z]+)\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
Имајте на уму да [а-з] у обрасцу регуларног израза у овом примеру значи било који знак од а до з (тј. мала абецеда), а + значи понављање претходног узорка (у овом случају [а-з]) једном или више пута. [а-з]+ одговара било ком низу који понавља један или више знакова малих слова.
. је мета карактер (знак са посебним значењем) и мора се изаћи са обрнутом косом цртом.
Пошто низови шаблона регуларног израза често користе много обрнутих косих црта, згодно је користити необрађене низове као у примеру.
Покреће се у методи објекта обрасца регуларног израза
Други начин за обраду регуларних израза у модулу ре је метода објекта обрасца регуларног израза.
Користећи ре.цомпиле(), можете компајлирати низ образаца регуларног израза да бисте креирали објекат обрасца регуларног израза.
p = re.compile(r'([a-z]+)@([a-z]+)\.com')
print(p)
# re.compile('([a-z]+)@([a-z]+)\\.com')
print(type(p))
# <class 're.Pattern'>
re.match()
,re.sub()
На пример, исти процес као и ове функције може се извршити као методе матцх(),суб() објеката регуларног израза.
m = p.match(s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
result = p.sub('new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
Све функције ре.ккк() описане у наставку су такође обезбеђене као методе објекта регуларног израза.
Ако понављате процес који користи исти образац, ефикасније је генерисати објекат регуларног израза помоћу ре.цомпиле() и користити га унаоколо.
У следећем узорку кода, функција се користи без компајлирања ради погодности, али ако желите да користите исти образац више пута, препоручује се да га преведете унапред и извршите као методу регуларног објекта израза.
подударање објекта
матцх(), сеарцх() итд. враћају одговарајући објекат.
s = 'aaa@xxx.com'
m = re.match(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(type(m))
# <class 're.Match'>
Упарени стринг и позиција се добијају коришћењем следећих метода објекта подударања.
- Сазнајте локацију утакмице:
start()
,end()
,span()
- Узмите одговарајући стринг:
group()
- Набавите стринг за сваку групу:
groups()
print(m.start())
# 0
print(m.end())
# 11
print(m.span())
# (0, 11)
print(m.group())
# aaa@xxx.com
Ако део шаблона регуларног израза приложите у низ са заградама(), део ће бити обрађен као група. У овом случају, стринг дела који одговара свакој групи у гроупс() може се добити као тупле.
m = re.match(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(m.groups())
# ('aaa', 'xxx', 'com')
Проверите да ли се почетак стринга поклапа, издвојите: матцх()
матцх() враћа одговарајући објекат ако се почетак стринга поклапа са шаблоном.
Као што је горе поменуто, објекат подударања се може користити за издвајање подударног подниза или једноставно за проверу да ли је направљено подударање.
матцх() ће проверити само почетак. Ако на почетку нема одговарајућег стринга, враћа Ноне.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.match(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
m = re.match(r'[a-z]+@[a-z]+\.net', s)
print(m)
# None
Проверите подударања која нису ограничена на почетак, издвојите: сеарцх()
Као и матцх(), враћа објекат подударања ако се подудара.
Ако постоји више одговарајућих делова, биће враћен само први одговарајући део.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
m = re.search(r'[a-z]+@[a-z]+\.net', s)
print(m)
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
m = re.search(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
Ако желите да добијете све одговарајуће делове, користите финдалл() или финдитер() као што је описано у наставку.
Проверите да ли се цео низ подудара: фуллматцх()
Да бисте проверили да ли цео стринг одговара шаблону регуларног израза, користите фуллматцх(). Ово је корисно, на пример, да проверите да ли је стринг валидан као адреса е-поште или не.
Ако се цео низ подудара, враћа се објекат подударања.
s = 'aaa@xxx.com'
m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
Ако постоје делови који се не подударају (само делимична поклапања или се уопште не подударају), враћа се ниједан.
s = '!!!aaa@xxx.com!!!'
m = re.fullmatch(r'[a-z]+@[a-z]+\.com', s)
print(m)
# None
Фуллматцх() је додат у Питхон 3.4. Ако желите да урадите исто у претходним верзијама, користите матцх() и одговарајући мета карактер $ на крају. Ако се цео стринг од почетка до краја не подудара, враћа Ноне.
s = '!!!aaa@xxx.com!!!'
m = re.match(r'[a-z]+@[a-z]+\.com$', s)
print(m)
# None
Добијте листу свих одговарајућих делова: финдалл()
финдалл() враћа листу свих одговарајућих подстрингова. Имајте на уму да елементи листе нису подударни објекти већ низови.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.findall(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# ['aaa@xxx.com', 'bbb@yyy.com', 'ccc@zzz.net']
Број подударних делова може се проверити коришћењем уграђене функције лен(), која враћа број елемената на листи.
print(len(result))
# 3
Груписање са заградама() у обрасцу регуларног израза враћа листу торки чији су елементи стрингови сваке групе. Ово је еквивалентно групама() у објекту подударања.
result = re.findall(r'([a-z]+)@([a-z]+)\.([a-z]+)', s)
print(result)
# [('aaa', 'xxx', 'com'), ('bbb', 'yyy', 'com'), ('ccc', 'zzz', 'net')]
Групне заграде () могу бити угнежђене, тако да ако желите да добијете и цело подударање, само ставите цело подударање у заграде ().
result = re.findall(r'(([a-z]+)@([a-z]+)\.([a-z]+))', s)
print(result)
# [('aaa@xxx.com', 'aaa', 'xxx', 'com'), ('bbb@yyy.com', 'bbb', 'yyy', 'com'), ('ccc@zzz.net', 'ccc', 'zzz', 'net')]
Ако није пронађено подударање, враћа се празан тупле.
result = re.findall('[0-9]+', s)
print(result)
# []
Узми све одговарајуће делове као итератор: финдитер()
финдитер() враћа све подударне делове као итератор. Елементи нису стрингови као финдалл(), већ се подударају објекти, тако да можете добити позицију (индекс) подударних делова.
Сам итератор се не може одштампати помоћу принт() да би се добио његов садржај. Ако користите уграђену функцију нект() или фор наредбу, садржај можете добити један по један.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
print(result)
# <callable_iterator object at 0x10b0efa90>
print(type(result))
# <class 'callable_iterator'>
for m in result:
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
Такође се може конвертовати у листу помоћу листе().
l = list(re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s))
print(l)
# [<re.Match object; span=(0, 11), match='aaa@xxx.com'>, <re.Match object; span=(13, 24), match='bbb@yyy.com'>, <re.Match object; span=(26, 37), match='ccc@zzz.net'>]
print(l[0])
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(type(l[0]))
# <class 're.Match'>
print(l[0].span())
# (0, 11)
Ако желите да добијете позицију свих одговарајућих делова, нотација разумевања листе је погоднија од листе().
print([m.span() for m in re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)])
# [(0, 11), (13, 24), (26, 37)]
Итератор вади елементе по реду. Имајте на уму да ако покушате да извучете више елемената након што дођете до краја, нећете остати без ичега.
result = re.finditer(r'[a-z]+@[a-z]+\.[a-z]+', s)
for m in result:
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
# <re.Match object; span=(13, 24), match='bbb@yyy.com'>
# <re.Match object; span=(26, 37), match='ccc@zzz.net'>
print(list(result))
# []
Замените одговарајуће делове: суб(), субн()
Користећи суб(), можете заменити подударни део другим низом. Замењени низ ће бити враћен.
s = 'aaa@xxx.com, bbb@yyy.com, ccc@zzz.net'
result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# new-address, new-address, ccc@zzz.net
print(type(result))
# <class 'str'>
Када се групише са заградама(), подударни низ се може користити у замењеном низу.
Подразумевано је подржано следеће: Имајте на уму да за нормалне стрингове који нису необрађени стрингови, обрнута коса црта мора бити наведена пре обрнуте косе црте да би се избегла обрнута коса црта.
\1 | Прва заграда |
\2 | Друга заграда |
\3 | Трећа заграда |
result = re.sub(r'([a-z]+)@([a-z]+)\.com', r'\1@\2.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net
?P<xxx>
Ако групи дате назив тако што ћете ово написати на почетку заграда обрасца регуларног израза, можете је навести користећи име уместо броја, као што је приказано испод.\g<xxx>
result = re.sub(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# aaa@xxx.net, bbb@yyy.net, ccc@zzz.net
Број аргумената одређује максималан број замена. Биће замењен само број са леве стране.
result = re.sub(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# new-address, bbb@yyy.com, ccc@zzz.net
субн() враћа тупле замењеног стринга (исто као повратна вредност суб()) и број замењених делова (број који одговара шаблону).
result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s)
print(result)
# ('new-address, new-address, ccc@zzz.net', 2)
Метод специфицирања аргумената је исти као суб(). Можете користити део груписан у заградама или навести број аргумената.
result = re.subn(r'(?P<local>[a-z]+)@(?P<SLD>[a-z]+)\.com', r'\g<local>@\g<SLD>.net', s)
print(result)
# ('aaa@xxx.net, bbb@yyy.net, ccc@zzz.net', 2)
result = re.subn(r'[a-z]+@[a-z]+\.com', 'new-address', s, count=1)
print(result)
# ('new-address, bbb@yyy.com, ccc@zzz.net', 1)
Подела стрингова са обрасцима регуларног израза: сплит()
сплит() дели стринг на делу који одговара шаблону и враћа га као листу.
Имајте на уму да ће прво и последње подударање садржати празне стрингове на почетку и на крају резултирајуће листе.
s = '111aaa222bbb333'
result = re.split('[a-z]+', s)
print(result)
# ['111', '222', '333']
result = re.split('[0-9]+', s)
print(result)
# ['', 'aaa', 'bbb', '']
Аргумент максплит специфицира максималан број подела (комада). Само број са леве стране ће бити подељен.
result = re.split('[a-z]+', s, 1)
print(result)
# ['111', '222bbb333']
Метазнакови регуларног израза, специјалне секвенце и упозорења у Питхон-у
Главни мета карактери регуларног израза (специјални знакови) и специјалне секвенце које се могу користити у Питхон 3 ре модулу су следеће
метакарактер | садржаја |
---|---|
. | Било који појединачни знак осим новог реда (укључујући нови ред са заставицом ДОТАЛЛ) |
^ | Почетак низа (такође одговара почетку сваког реда са заставицом МУЛТИЛИНЕ) |
$ | Крај низа (такође одговара крају сваког реда са заставицом МУЛТИЛИНЕ) |
* | Поновите претходни образац више од 0 пута |
+ | Поновите претходни образац најмање једном. |
? | Поновите претходни образац 0 или 1 пута |
{m} | Поновите претходни образац м пута |
{m, n} | Последњи образац.m ~n понављање |
[] | Скуп карактера[] Одговара било ком од ових знакова |
| | ИЛИA|B Одговара или А или Б шаблону |
посебан редослед | садржаја |
---|---|
\d | Уницоде децимални бројеви (ограничени на АСЦИИ бројеве помоћу АСЦИИ заставице) |
\D | \d Што значи супротно од овога. |
\s | Уницоде размаци (ограничено на АСЦИИ знакове размака помоћу АСЦИИ заставице) |
\S | \s Што значи супротно од овога. |
\w | Уницоде знакови речи и доње црте (ограничено на АСЦИИ алфанумеричке знакове и доње црте помоћу АСЦИИ заставице) |
\W | \w Што значи супротно од овога. |
Нису сви наведени у овој табели. Погледајте званичну документацију за комплетну листу.Нису сви наведени у овој табели. Погледајте званичну документацију за комплетну листу.
Такође имајте на уму да су нека значења различита у Питхон-у 2.
Постављање заставе
Као што је приказано у табели изнад, неки мета знакови и специјалне секвенце мењају свој режим у зависности од заставе.
Овде су покривене само главне заставе. За остало погледајте званичну документацију.
Ограничено на АСЦИИ знакове: ре.АСЦИИ
\w
Ово ће такође одговарати двобајтним кањи, алфанумеричким знаковима итд. подразумевано за Питхон 3 стрингове. Није еквивалентно следећем јер није стандардни регуларни израз.[a-zA-Z0-9_]
m = re.match(r'\w+', '漢字ABC123')
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>
m = re.match('[a-zA-Z0-9_]+', '漢字ABC123')
print(m)
# None
Ако наведете ре.АСЦИИ за заставице аргумената у свакој функцији или додате следећу уметнуту заставицу на почетак низа обрасца регуларног израза, она ће одговарати само АСЦИИ знаковима (неће одговарати двобајтним јапанским, алфанумеричким знаковима итд. .).(?a)
У овом случају, следећа два су еквивалентна.\w
#ERROR![a-zA-Z0-9_]
m = re.match(r'\w+', '漢字ABC123', flags=re.ASCII)
print(m)
# None
m = re.match(r'(?a)\w+', '漢字ABC123')
print(m)
# None
Исто важи и за компајлирање са ре.цомпиле(). Користите заставице за аргументе или инлине заставице.
p = re.compile(r'\w+', flags=re.ASCII)
print(p)
# re.compile('\\w+', re.ASCII)
print(p.match('漢字ABC123'))
# None
p = re.compile(r'(?a)\w+')
print(p)
# re.compile('(?a)\\w+', re.ASCII)
print(p.match('漢字ABC123'))
# None
АСЦИИ је такође доступан као кратки облик ре. О: Можете користити било које.
print(re.ASCII is re.A)
# True
На \В, супротно од \В, такође утичу ре.АСЦИИ и инлине заставице.
m = re.match(r'\W+', '漢字ABC123')
print(m)
# None
m = re.match(r'\W+', '漢字ABC123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 11), match='漢字ABC123'>
Као и код \в, следећа два подразумевано одговарају једнобајтним и двобајтним карактерима, али су ограничени на једнобајтне знакове ако су специфициране ре.АСЦИИ или инлине заставице.
- Спојите бројеве
\d
- Одговара празном простору
\s
- Одговара не-бројевима
\D
- Одговара било којем не-размаку.
\S
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123')
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# <re.Match object; span=(0, 3), match='123'>
m = re.match(r'\d+', '123', flags=re.ASCII)
print(m)
# None
m = re.match(r'\s+', ' ') # full-width space
print(m)
# <re.Match object; span=(0, 1), match='\u3000'>
m = re.match(r'\s+', ' ', flags=re.ASCII)
print(m)
# None
Не разликују:re.IGNORECASE
Подразумевано је осетљиво на велика и мала слова. Да бисте упарили оба, морате да укључите и велика и мала слова у образац.
re.IGNORECASE
Ако је ово наведено, подудараће се без обзира на велика и мала слова. Еквивалентно заставици и у стандардним регуларним изразима.
m = re.match('[a-zA-Z]+', 'abcABC')
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
m = re.match('[a-z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
m = re.match('[A-Z]+', 'abcABC', flags=re.IGNORECASE)
print(m)
# <re.Match object; span=(0, 6), match='abcABC'>
Можете користити мање или једнако.
- инлине флаг
(?i)
- скраћеница
re.I
Ускладите почетак и крај сваког реда:re.MULTILINE
^
Мета знакови у овом регуларном изразу одговарају почетку стринга.
Подразумевано, само почетак целог стринга се подудара, али ће следећи такође одговарати почетку сваког реда. Еквивалентно заставици м у стандардним регуларним изразима.re.MULTILINE
s = '''aaa-xxx
bbb-yyy
ccc-zzz'''
print(s)
# aaa-xxx
# bbb-yyy
# ccc-zzz
result = re.findall('[a-z]+', s)
print(result)
# ['aaa', 'xxx', 'bbb', 'yyy', 'ccc', 'zzz']
result = re.findall('^[a-z]+', s)
print(result)
# ['aaa']
result = re.findall('^[a-z]+', s, flags=re.MULTILINE)
print(result)
# ['aaa', 'bbb', 'ccc']
$
Одговара крају низа. Подразумевано, само крај целог стринга се подудара.re.MULTILINE
Ако наведете ово, такође ће одговарати крају сваког реда.
result = re.findall('[a-z]+$', s)
print(result)
# ['zzz']
result = re.findall('[a-z]+$', s, flags=re.MULTILINE)
print(result)
# ['xxx', 'yyy', 'zzz']
Можете користити мање или једнако.
- инлине флаг
(?m)
- скраћеница
re.M
Наведите више заставица
|
Ако желите да омогућите више заставица у исто време, користите ово. У случају инлине заставица, сваки знак мора бити праћен словом као што је приказано испод.(?am)
s = '''aaa-xxx
漢漢漢-字字字
bbb-zzz'''
print(s)
# aaa-xxx
# 漢漢漢-字字字
# bbb-zzz
result = re.findall(r'^\w+', s, flags=re.M)
print(result)
# ['aaa', '漢漢漢', 'bbb']
result = re.findall(r'^\w+', s, flags=re.M | re.A)
print(result)
# ['aaa', 'bbb']
result = re.findall(r'(?am)^\w+', s)
print(result)
# ['aaa', 'bbb']
Похлепне и непохлепне утакмице
Ово је општи проблем са регуларним изразима, а не само проблем са Питхон-ом, али писаћу о томе јер ме често доводи у невоље.
Подразумевано, следеће је похлепно подударање, које одговара најдужем могућем низу.
*
+
?
s = 'aaa@xxx.com, bbb@yyy.com'
m = re.match(r'.+com', s)
print(m)
# <re.Match object; span=(0, 24), match='aaa@xxx.com, bbb@yyy.com'>
print(m.group())
# aaa@xxx.com, bbb@yyy.com
Тхе ? након што ће резултирати не-похлепним, минималним подударањем, који одговара најкраћем могућем низу.
*?
+?
??
m = re.match(r'.+?com', s)
print(m)
# <re.Match object; span=(0, 11), match='aaa@xxx.com'>
print(m.group())
# aaa@xxx.com
Имајте на уму да подразумевано похлепно подударање може да одговара неочекиваним стринговима.