Muntazam ifodalar (RegExp)

Kvantorlar: +, *, ?, {n,m}

Kvantor (quantifier) โ€” muntazam ifodada biror belgi yoki guruh necha marta takrorlanishi kerakligini bildiruvchi maxsus belgi. Masalan, \d+ โ€” "bir yoki undan ko'p raqam" degani. Kvantorlar RegExp'ni haqiqatan kuchli qiladi: aynan ular yordamida biz uzunligi oldindan noma'lum bo'lgan matnlarni โ€” raqamlar, so'zlar, teglar โ€” tuta olamiz.

Aniq miqdor: {n}

Eng oddiy kvantor โ€” figurali qavs ichidagi aniq son. {n} โ€” undan oldingi belgi roppa-rosa n marta takrorlanishini talab qiladi.

Masalan, \d{4} โ€” ketma-ket kelgan to'rtta raqam degani (masalan yil):

kvantor-n.js
// natija shu yerda chiqadi

E'tibor bering: kvantor faqat o'zidan oldingi bitta belgi yoki guruhga ta'sir qiladi. \d{4} da bu \d, ya'ni bitta raqam sinfi.

Oraliq: {n,m}

{n,m} โ€” takrorlanishlar soni n dan m gacha (ikkalasi ham kiritilgan) bo'lishi mumkin. Dvigatel iloji boricha ko'proq belgini olishga harakat qiladi (bu haqda pastda batafsil).

kvantor-nm.js
// natija shu yerda chiqadi
Yuqoridagi 12345 dan atigi 1234 olindi: kvantor eng ko'pi bilan 4 ta raqamni oladi, oxirgi 5 esa keyingi mos kelishga qoladi (u yolg'iz bo'lgani uchun {2,4} ga yetmaydi va tashlab ketiladi).

Yuqori chegarani tushirib qoldirish mumkin: {n,} โ€” "n yoki undan ko'p". Masalan, \d{3,} โ€” kamida uchta raqam:

kvantor-n-ochiq.js
// natija shu yerda chiqadi

Qisqartmalar: +, ?, *

Amaliyotda uchta oraliq juda ko'p ishlatilgani uchun ularga qisqa belgilar berilgan:

Mana + yordamida matndan barcha sonlarni (uzunligidan qat'i nazar) ajratamiz:

kvantor-plus.js
// natija shu yerda chiqadi

? โ€” belgini ixtiyoriy qiladi. Masalan, "color" va "colour" โ€” ikkalasini ham tutamiz. u? degani u harfi bo'lishi ham, bo'lmasligi ham mumkin:

kvantor-savol.js
// natija shu yerda chiqadi

* โ€” belgi umuman bo'lmasligi ham mumkin. Masalan, -* chiziqchalar ketma-ketligi (bo'sh ham) ni tutadi. Farqni ko'ramiz:

kvantor-yulduz.js
// natija shu yerda chiqadi
Eslab qolish oson: + = "kamida bitta", ? = "bor yoki yo'q", * = "bor bo'lsa mayli, yo'q bo'lsa ham mayli".

Ochko'z rejim (greedy)

Kvantorlar sukut bo'yicha ochko'z (greedy) ishlaydi: dvigatel iloji boricha ko'proq belgini olishga urinadi. Bu ba'zan kutilmagan natija beradi.

Klassik misol: qo'shtirnoq ichidagi matnni tutmoqchimiz. ".+" deb yozsak nima bo'ladi?

ochkoz.js
// natija shu yerda chiqadi

Nega bunday bo'ldi? .+ ochko'z bo'lgani uchun dvigatel birinchi qo'shtirnoqdan keyin matn oxirigacha hamma narsani "yamlab" oladi, so'ng oxirgi " ni topish uchun orqaga qaytadi va eng oxirgi qo'shtirnoqni tanlaydi. Natijada ikkala qo'shtirnoq oralig'idagi hamma narsa bitta mos kelish bo'lib qoladi.

Dangasa rejim (lazy)

Ochko'zlikni to'xtatish uchun kvantordan keyin ? qo'yamiz. Bu uni dangasa (lazy) qiladi: dvigatel endi iloji boricha kamroq belgini oladi, ya'ni birinchi mos kelishda to'xtaydi.

.+? โ€” "iloji boricha kam belgi, lekin kamida bitta":

dangasa.js
// natija shu yerda chiqadi
? belgisi ikki xil vazifada ishlaydi: agar u o'zi kvantor bo'lsa โ€” "0 yoki 1" degani; agar boshqa kvantordan keyin kelsa โ€” o'sha kvantorni dangasa qiladi. Masalan +?, *?, {2,4}?.

Dangasalik faqat o'zi qo'yilgan kvantorga ta'sir qiladi, boshqalari ochko'zligicha qoladi. Shuning uchun murakkab shablonlarda har bir kvantorni alohida sozlash mumkin.

Amaliy misol: HTML teglarni ajratish

Matndan barcha oddiy HTML teglarni ajratamiz. Ochko'z <.+> xato ishlaydi โ€” u birinchi < dan oxirgi > gacha hammasini oladi. To'g'ri yechim โ€” dangasa <.+?> yoki undan ham yaxshisi <[^>]+>:

teg-ajratish.js
// natija shu yerda chiqadi
Ko'p hollarda dangasa kvantor o'rniga inkor belgilar sinfi (masalan [^>]+) yaxshiroq: u tezroq ishlaydi va "ortga qaytish" (backtracking) muammolaridan xoli bo'ladi.

Amaliy misol: kasr sonlar

Butun va kasr sonlarni birga tutish uchun kvantorlarni birlashtiramiz. Nuqtadan keyingi qism ixtiyoriy bo'lishi kerak, shuning uchun butun bir guruhni ? bilan ixtiyoriy qilamiz:

kasr-son.js
// natija shu yerda chiqadi

Bu yerda \d+ โ€” butun qism, (\.\d+)? โ€” nuqta va undan keyingi raqamlar, ammo butun guruh ? tufayli ixtiyoriy. Shu bois 12 ham, 12.5 ham tutiladi.

Ochko'z kvantorlar juda uzun matnlarda "katastrofik backtracking"ga (dvigatel millionlab variantni sinab, qotib qolishi) olib kelishi mumkin. Ayniqsa (a+)+ kabi ichma-ich kvantorlardan ehtiyot bo'ling.

Xulosa