Python да регуляр ифодаларнинг ғадаблигини чеклаш
Регуляр ифодалар сунъий равишда ғадабли. Бу улар максимал имкониятли белгилар сонини олишини англатади. Келинг, мисол билан кўриб чиқайлик. Фарз қилайлик, бизда мана бу қатор мавжуд:
txt = 'aeeex zzz x kkk'
Бу қаторда биз қуйидаги намуна бўйича
'aeeex' қисм қаторини топишни истаймиз:
'a' ҳарфи, сўнгра ихтиёрий белги
бир ёки бир неча марта, сўнгра 'x' ҳарфи:
res = re.sub('a.+x', '!', txt)
print(res)
Биз '! zzz x kkk' қаторини олишимиз керак бўлса-да, '! kkk' қатори чиқади.
Ҳаммаси ўзида, бизнинг регуляр ифодамиз
'a' ҳарфидан 'x' ҳарфигача бўлган барча белгиларни излайди.
Аммо бизнинг қаторимизда иккита 'x' ҳарфи бор!
Ғадаблик сабаб шунда бўладики,
регуляр ифода охирги 'x' гача излаб,
бизга керакли бўлмаган нарсани ҳам олиб қўяди.
Албатта, кўпинча бундай ҳаракат биз учун зарур бўлади. Аммо айнан бу ҳолатда ғадабликни бекор қилиш ва регуляр ифодага биринчи 'x' гача излашни айтиш керак. Бу ҳолатда такрорлаш операторидан кейин сўров белгисини қўйиш керак:
res = re.sub('a.+?x', '!', txt)
print(res) # '! zzz x kkk' қаторини чиқаради
Ғадабликни барча такрорлаш операторлари учун чеклаш мумкин:
*, ? ҳамда
{} - мана бу йўл билан: *?, ??
ва {}?.
Берилган қатор:
txt = 'aba accca azzza wwwwa'
Ҳар икки томони 'a' ҳарфлари билан туғалланган барча қаторларни топадиган
ва уларнинг ҳар бирини '!' билан алмаштирадиган регуляр ифода ёзинг.
'a' ҳарфлари орасида ихтиёрий белги ('a' дан бошқа) бўлиши мумкин.