Asosiy kontentga o‘tish
Innovialabs

Murakkab regex: lookahead, lookbehind va nomlangan guruhlar

Chuqur3 daq

Qisqacha

Lookaround kontekstni ushlamasdan tekshiradi, nomlangan guruhlar mosliklarni o‘qiladigan qiladi, (a+)+ kabi ichma-ich kvantifikatorlar esa halokatli backtracking va ReDoS’ning asosiy manbai.

Murakkab konstruksiyalar nima beradi

Oddiy regex «bunday matn bormi» degan savolga javob beradi. Murakkab konstruksiyalar aniqroq aytishga imkon beradi:

  • lookaround — «moslik nimadirning oldida yoki ortida turishi kerak», lekin o‘sha «nimadir» natijaga kirmaydi;
  • nomlangan guruhlar — moslik qismlarini raqam bo‘yicha emas, nom bo‘yicha olamiz;
  • ushlamaydigan guruhlar — ortiqcha ushlashlarsiz guruhlaymiz;
  • dangasa kvantifikatorlar — maksimum o‘rniga minimumni olamiz;
  • orqa havolalar — allaqachon topilgan matn takrorlanishini talab qilamiz.

Lookahead va lookbehind

Bular nol kenglikdagi tekshiruvlar: ular qo‘shni matnga qaraydi, lekin uni «yemaydi».

KonstruksiyaMa’nosi
(?=X)keyin X keladi
(?!X)keyin X kelmaydi
(?<=X)oldida X turadi
(?<!X)oldida X turmaydi

Klassik misol — sonning xonalarini bo‘sh joy bilan ajratish:

"1234567".replace(/\B(?=(\d{3})+(?!\d))/g, " "); // "1 234 567"

Pozitsiya mos keladi, agar undan keyin son oxirigacha aynan uchtadan raqamli guruhlar kelsa. Raqamlarning o‘zi ushlanmaydi, shuning uchun almashtirish hech narsani o‘chirmasdan bo‘sh joy qo‘shadi.

Ketma-ket bir nechta lookahead shartlarni istalgan tartibda tekshirish uchun qulay: ^(?=.*\d)(?=.*[a-z]).{8,}$ — kamida 8 belgi, raqam va kichik harf bor.

Lookbehind markerdan keyingi qiymatni ajratib oladi: (?<=\$)\d+ $25 ichidan 25 ni topadi. Muhim farq: Python’dagi re moduli qat’iy uzunlikdagi lookbehind talab qiladi, zamonaviy JavaScript dvigatellarida esa uzunlik o‘zgaruvchan bo‘lishi mumkin.

Nomlangan va ushlamaydigan guruhlar

Sintaksis tillar orasida farq qiladi:

const m = "2026-10-19".match(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/);
m.groups.y; // "2026"
"2026-10-19".replace(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/, "$<d>.$<m>.$<y>");
import re
re.sub(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})", r"\g<d>.\g<m>.\g<y>", "2026-10-19")

Agar guruh faqat | yoki kvantifikator uchun kerak bo‘lsa, uni ushlamaydigan qiling: (?:https?|ftp)://. Boshqa guruhlarning raqamlari siljimaydi, dvigatelga esa ish kamroq.

Ochko‘z va dangasa kvantifikatorlar

Sukut bo‘yicha *, +, {n,} ochko‘z — iloji boricha ko‘p oladi. <b>x</b> satrida <.+> butun satrni ushlaydi, dangasa <.+?> esa faqat <b> ni.

Ko‘pincha dangasalik o‘rniga ruxsat etilgan belgilarni aniq tasvirlash yaxshiroq: <[^>]+>. Bu ham tushunarliroq, ham tezroq, chunki dvigatel orqaga qaytishi shart emas.

Orqa havolalar

Orqa havola matn takrorlanishini talab qiladi: \b(\w+)\s+\1\b «the the» kabi takrorlangan so‘zni topadi. Nomlangan guruhlar uchun: JavaScript’da \k<word>, Python’da (?P=word).

Halokatli backtracking va ReDoS

JavaScript, Python, Java va boshqa ko‘plab tillarning dvigatellari backtracking orqali ishlaydi: muvaffaqiyatsizlikda kirishni bo‘lishning boshqa variantlarini sinab ko‘radi. ^(a+)+$ ifodasi oxirida ! bo‘lgan uzun a satrida eksponensial sondagi variantlarni sinaydi va jarayonni «qotirib» qo‘yadi. Agar bunday ifoda foydalanuvchi kiritgan ma’lumotni tekshirsa, bu ReDoS — bitta satr bilan xizmatni ishdan chiqarish.

Qanday himoyalanish mumkin:

  • bir xil matn ustidagi ichma-ich kvantifikatorlardan qoching: (a+)+, (\w*)*, (.*,)*;
  • bir-biriga kesishadigan alternativalardan qoching: (a|a)*, (\d|\d\d)+;
  • regex’ni ishga tushirishdan oldin kirish uzunligini cheklang;
  • mavjud bo‘lsa, atomar guruhlar (?>...) va egalovchi kvantifikatorlar a++ dan foydalaning — ular orqaga qaytishni taqiqlaydi (Python’ning yangi versiyalarida ular re ga qo‘shilgan);
  • ishonchsiz shablonlar yoki kirish uchun RE2 kabi backtracking’siz dvigatellarni oling.

Keng tarqalgan xatolar

  • JavaScript’da barcha moslikni almashtirishda g bayrog‘ini unutish.
  • Validatsiyada ^ va $ langarlarining yo‘qligi — tekshiruv satr bo‘lagi bo‘yicha o‘tib ketadi.
  • Python’da raw-satr r"..." o‘rniga oddiy satr, natijada \b backspace’ga aylanadi.
  • Parser yoki ikkita oddiy tekshiruv osonroq bo‘lgan joyda bitta ulkan regex.

Ko‘p beriladigan savollar

Ehtimol, ichida turli uzunlikdagi alternativalar yoki kvantifikator bor. re moduli faqat qat’iy uzunlikdagi lookbehind’ni qo‘llab-quvvatlaydi. Uni bir nechta lookbehind’ga bo‘ling yoki uchinchi tomon regex kutubxonasidan foydalaning.

Yana o‘qing

G‘oya yoki vazifangiz bormi? Bizga aytib bering

Ish kuni davomida javob beramiz va yechim taklif qilamiz. Konsultatsiya bepul.