Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Ushlovchi guruh: ( )
- 2.1 Qavslar bo'lakni ushlaydi
- 2.2 Guruhlar qanday raqamlanadi
- 2.3 Quantifier butun guruhga
- 3. Ushlamaydigan guruh: (?:...)
- 4. Nomlangan guruh: (?<nom>...)
- 4.1 Raqam o'rniga nom
- 4.2 Destructuring bilan
- 4.3 Qaysi qavsni tanlash
- 5. Alternation: | — "yoki"
- 5.1 Bir nechta variant
- 5.2 | eng "kuchsiz" belgi
- 5.3 Birinchi mos kelgan variant yutadi
- 5.4 Soat 00–23: va'da bajarildi
- 6. Qayta havola: \1 va \k<nom>
- 6.1 "Xuddi o'sha bo'lak yana"
- 6.2 Telefon: "hammasi bir xil"
- 7. Guruhlar va metodlar
- 7.1 g bilan match guruhlarni yo'qotadi
- 7.2 replace da $1
- 7.3 split va guruh
- 8. Yangi imkoniyat: takrorlangan nomlar (ES2025)
- 9. Ko'p uchraydigan xatolar
- 9.1 | ni qavssiz yozish
- 9.2 Qisqa variantni oldinga qo'yish
- 9.3 Mos kelmagan guruh — undefined
- 9.4 Qavs qo'shib, raqamlarni siljitish
- 9.5 Mavjud bo'lmagan $2
- 10. Mashqlar
- 1-mashq (oson): Vaqtni bo'laklash
- 2-mashq (o'rta): Taom yoki ichimlik
- 3-mashq (qiyin): Menyu matnidan obyektlar
- 4-mashq: Vazifalar qadami — matndagi muddat
- 11. Real ishda
- Xulosa
- Manbalar
Regex guruhlari: ( ), (?:), (?<nom>) va | alternation
Qisqacha: Qavslar
( )naqshning bir qismini guruh qiladi: quantifier butun guruhga tegadi ((ha)+) va topilgan bo'lak alohida "ushlanadi" —moslik[1],moslik[2].(?:...)faqat guruhlaydi, ushlamaydi.(?<yil>...)guruhga nom beradi — natijamoslik.groups.yilda. Vertikal chiziq|— "yoki":osh|manti.
Bu darsda
- Qavslar bilan naqsh bo'lagini guruhlaysiz va topilgan qismlarni
[1],[2]orqali olasiz. - Nomlangan guruh
(?<nom>...)bilan natijanigroups.yilkabi o'qiladigan qilasiz. |bilan "yoki" yozasiz va u nega ko'pincha qavs ichida turishini tushuntira olasiz.\1va\k<nom>bilan "oldin topilgan bo'lak yana takrorlansin" deysiz.replaceda$1bilan topilgan bo'laklarni boshqa tartibda joylashtirasiz.
Oldin bilishingiz kerak: RegExp asoslari va metodlari, Langarlar va so'z chegarasi, Quantifierlar: greedy va lazy, Obyekt destructuring.
1. Nega bu kerak?
Sardor bron formasidan sanani oladi. Formada sana 2026-10-07 ko'rinishida keladi. Jasur aka esa uni 07.10.2026 ko'rinishida ko'rmoqchi. Buning uchun yil, oy va kunni alohida olish kerak.
Hozirgacha bilganlarimiz bilan sanani topish mumkin:
const bron = "Bron: 2026-10-07, soat 19:30";
console.log(bron.match(/\d{4}-\d{2}-\d{2}/)[0]); // 2026-10-07Lekin natija — bitta yaxlit satr. Undan yilni olish uchun yana split("-") yoki slice kerak. Regex sanani qismlarga bo'lib "bilgan" edi-ku: avval to'rt raqam, keyin ikki, keyin yana ikki. Shu bilimni yo'qotmasdan olish mumkinmi?
O'tgan darslarda yana uchta savol ochiq qoldi:
(ha)+— butunhani takrorlash (Quantifierlar darsida va'da qilingan);- soat
29:00ni rad etish — "2bilan boshlansa, keyin faqat0–3" degan "yoki"li shart (Belgilar va belgi klasslari darsidan); - telefonda "yo hamma bo'sh joy bor, yo hech biri" degan qoida.
Uchalasining javobi — guruhlar. Bugun qavslarning to'rt xil ishini ko'ramiz.
2. Ushlovchi guruh: ( )
2.1 Qavslar bo'lakni ushlaydi
Guruh (group) — naqshning qavs ichiga olingan qismi. Oddiy qavs ( ) ikki ish qiladi. Birinchisi — ichidagini bitta bo'lakka aylantiradi. Ikkinchisi — shu bo'lakka mos kelgan matnni alohida eslab qoladi. Shuning uchun u ushlovchi guruh (capturing group) deb ataladi.
Sanadagi uch qismni qavsga olamiz:
const bron = "Bron: 2026-10-07, soat 19:30";
const moslik = bron.match(/(\d{4})-(\d{2})-(\d{2})/);
console.log(moslik[0]); // 2026-10-07
console.log(moslik[1]); // 2026
console.log(moslik[2]); // 10
console.log(moslik[3]); // 07[0] — butun moslik, buni bilasiz. [1], [2], [3] — guruhlar, chapdan o'ngga tartib bilan. Naqsh o'zgarmadi: faqat qavslar qo'shildi. Mos keladigan matn ham o'sha. Farqi — regex endi bo'laklarni ham qaytaradi.
Butun natijani chiqarsak:
const bron = "Bron: 2026-10-07, soat 19:30";
console.log(bron.match(/(\d{4})-(\d{2})-(\d{2})/));Konsolda:
[
'2026-10-07',
'2026',
'10',
'07',
index: 6,
input: 'Bron: 2026-10-07, soat 19:30',
groups: undefined
]Tanish massiv, faqat endi uzunroq. groups hali ham undefined — u nomlangan guruhlar uchun, ularga birozdan keyin yetamiz.
Maydonda sinang. Mosliklar jadvalida har moslik ostida guruhlar ham ko'rinadi — $1, $2, $3:
$1 — "birinchi guruh" degan yozuv. Uni replace da ham ishlatamiz.
2.2 Guruhlar qanday raqamlanadi
Guruh raqami — ochuvchi qavsning tartibi. Qavslar ichma-ich bo'lsa ham shu qoida:
const vaqt = "soat 19:30".match(/((\d{2}):(\d{2}))/);
console.log(vaqt[1]); // 19:30
console.log(vaqt[2]); // 19
console.log(vaqt[3]); // 30Birinchi ochuvchi qavs — tashqi, u butun 19:30 ni o'rab turibdi. Ikkinchisi — soat, uchinchisi — daqiqa. Qavslarni chapdan sanang: ( uchragan tartib — guruh raqami.
2.3 Quantifier butun guruhga
O'tgan darsda /ha+/ faqat a ni takrorlagan edi. Qavs bilan endi butun ha takrorlanadi:
haaa dan faqat ha olindi: guruh ha ni takrorlaydi, a ni emas.
Bitta nozik joy bor. Guruh takrorlansa, u faqat oxirgi aylanishni eslab qoladi:
console.log("hahaha".match(/(ha)+/)[0]); // hahaha
console.log("hahaha".match(/(ha)+/)[1]); // haButun moslik hahaha, [1] esa ha — uchinchi, oxirgi ha. Hamma takrorlarni alohida olish kerak bo'lsa — guruhni takrorlamang, g bilan matchAll ishlating.
Tekshirib ko'ring:
"Soat 7:05".match(/(\d+):(\d+)/)natijasida[2]nima?
Javob
"05". Ikkinchi ochuvchi qavs — daqiqa guruhi. Natija satr: guruhlar har doim matn qaytaradi, son kerak bo'lsa Number("05") qiling.
3. Ushlamaydigan guruh: (?:...)
Ba'zan qavs faqat guruhlash uchun kerak: quantifier qo'yish yoki "yoki"ni chegaralash uchun. Topilgan bo'lak esa kerak emas. Shunda qavs ochilgandan keyin ?: yoziladi: (?:...) — ushlamaydigan guruh (non-capturing group).
console.log("hahaha".match(/(ha)+/));
console.log("hahaha".match(/(?:ha)+/));Konsolda:
[ 'hahaha', 'ha', index: 0, input: 'hahaha', groups: undefined ]
[ 'hahaha', index: 0, input: 'hahaha', groups: undefined ]Moslik bir xil. Ikkinchisida ortiqcha 'ha' yo'q.
Nega bu muhim? Ikki sabab bor:
- Raqamlar siljimaydi. Naqshga yangi qavs qo'shsangiz, undan keyingi hamma guruh raqami bittaga suriladi. Kodda
[2]ishlatgan joylar jimgina boshqa narsani ola boshlaydi.(?:...)raqamga ta'sir qilmaydi. - Niyat aniq. O'qigan odam biladi: bu qavs faqat guruhlash uchun.
O'tgan darslardagi ikki misolni endi o'qiy olasiz. "Ixtiyoriy so'm" — (?: so'm)?, butun so'z ixtiyoriy:
const narxlar = "35000 so'm, 5000";
const naqsh = /\d+(?: so'm)?/g;
console.log(narxlar.match(naqsh)); // [ "35000 so'm", '5000' ]Langarlar darsida esa HTML pattern atributi naqshni ^(?:...)$ ga o'raydi, degan edik. Endi tushunarli: brauzer naqshingizni guruhlaydi, lekin hech narsani ushlamaydi.
4. Nomlangan guruh: (?<nom>...)
4.1 Raqam o'rniga nom
moslik[1], moslik[2] — qaysi biri yil, qaysi biri kun? Kodni o'qigan odam naqshga qaytib, qavslarni sanashi kerak. Nomlangan guruh (named group) buni hal qiladi: qavs ichida ?<nom> yoziladi.
const bron = "Bron: 2026-10-07, soat 19:30";
const naqsh = /(?<yil>\d{4})-(?<oy>\d{2})-(?<kun>\d{2})/;
const moslik = bron.match(naqsh);
console.log(moslik.groups.yil); // 2026
console.log(moslik.groups);Konsolda:
2026
[Object: null prototype] { yil: '2026', oy: '10', kun: '07' }groups endi obyekt: kalitlar — guruh nomlari, qiymatlar — topilgan matn. [Object: null prototype] — Node shuni aytyapti: bu obyektning prototipi yo'q, unda toString kabi meros metodlar ham yo'q. Brauzer konsoli shunchaki {yil: '2026', oy: '10', kun: '07'} deb ko'rsatadi — ma'nosi bir xil.
Nomlangan guruh raqamini ham saqlaydi: moslik[1] baribir 2026. Nom — qo'shimcha qulaylik.
4.2 Destructuring bilan
groups — oddiy obyekt kabi ishlaydi, shuning uchun Obyekt destructuring bilan qisqa yoziladi. Sardorning masalasi:
const bron = "Bron: 2026-10-07, soat 19:30";
const naqsh = /(?<yil>\d{4})-(?<oy>\d{2})-(?<kun>\d{2})/;
const { yil, oy, kun } = bron.match(naqsh).groups;
console.log(`${kun}.${oy}.${yil}`); // 07.10.2026Uch qatorda sana ajratildi va qayta yig'ildi. Naqshni o'qigan odam ham, natijani ishlatgan odam ham bir xil nomlarni ko'radi.
Maslahat: Bir yoki ikki guruh bo'lsa, raqam ham tushunarli. Uch va undan ko'p guruh bo'lsa yoki naqsh kodning bir joyida, natija boshqa joyida ishlatilsa — nom bering. Kelajakdagi o'zingiz rahmat aytasiz.
Tekshirib ko'ring:
/(?<soat>\d+):(?<daqiqa>\d+)/naqshidamoslik[2]vamoslik.groups.daqiqabir xil qiymatmi?
Javob
Ha. Nomlangan guruh ham raqamlanadi: soat — 1, daqiqa — 2. Ikkala yo'l bilan ham bir xil matn olinadi.
4.3 Qaysi qavsni tanlash
Endi uch xil qavsni bilasiz. Tanlash uchun ikki savol yetarli:
flowchart TD
Q{"Topilgan bo'lak kerakmi?"} -->|"Yo'q, faqat guruhlash"| N["(?:...) — ushlamaydi"]
Q -->|"Ha"| K{"Guruhlar ko'pmi?"}
K -->|"1–2 ta"| R["( ) — natija [1], [2]"]
K -->|"3 va undan ko'p"| M["(?#lt;nom#gt;...) — groups.nom"]5. Alternation: | — "yoki"
5.1 Bir nechta variant
Alternation — vertikal chiziq | bilan yoziladigan "yoki". osh|manti — "osh yoki manti". Klass [...] bitta belgi uchun variant beradi, | esa butun bo'laklar uchun:
Variantlar soni cheklanmagan. Har biri to'liq naqsh bo'lishi mumkin: \d+ so'm|bepul.
5.2 | eng "kuchsiz" belgi
| naqshni butunlay ikkiga bo'ladi — chap tomonidagi hamma narsa bir variant, o'ng tomonidagi hammasi ikkinchi. Bu ko'p xatoga sabab bo'ladi. Sardor "faqat osh yoki faqat manti" deb tekshirmoqchi edi:
console.log(/^osh|manti$/.test("oshpaz")); // true
console.log(/^(?:osh|manti)$/.test("oshpaz")); // falseBirinchi naqsh aslida "^osh yoki manti$" — ya'ni "osh bilan boshlanadi yoki manti bilan tugaydi". oshpaz osh bilan boshlanadi — o'tib ketdi. Ikkinchisida | qavs ichida: langarlar ikkala variantga ham tegishli.
Qoida: | ni deyarli har doim qavs ichiga oling. Ushlash kerak bo'lmasa — (?:...).
5.3 Birinchi mos kelgan variant yutadi
Dvigatel variantlarni chapdan o'ngga sinaydi va birinchi mos kelganida to'xtaydi. Eng uzunini qidirmaydi:
console.log("oshxona".match(/osh|oshxona/)[0]); // osh
console.log("oshxona".match(/oshxona|osh/)[0]); // oshxonaBirinchi naqshda osh darhol mos keldi — oshxona hatto sinab ko'rilmadi. Qoida: bir variant ikkinchisining boshi bo'lsa, uzunini oldinga qo'ying. Yoki ikkalasini \b bilan o'rang.
5.4 Soat 00–23: va'da bajarildi
Belgilar va belgi klasslari darsida [0-2]\d:[0-5]\d naqshi 29:00 ni o'tkazib yuborgan edi. Soatning ikkinchi raqami birinchisiga bog'liq. Buni ikki variant bilan yozamiz:
- birinchi raqam
0yoki1bo'lsa — ikkinchisi istalgan:[01]\d; - birinchi raqam
2bo'lsa — ikkinchisi faqat0–3:2[0-3].
const vaqt = /^(?:[01]\d|2[0-3]):[0-5]\d$/;
console.log(vaqt.test("07:00")); // true
console.log(vaqt.test("23:59")); // true
console.log(vaqt.test("29:00")); // false
console.log(vaqt.test("24:00")); // falseQavs bu yerda shart: busiz | butun naqshni ^[01]\d va 2[0-3]:[0-5]\d$ ga bo'lib yuborardi.
Tekshirib ko'ring:
/^choy|qahva$/naqshi"choyxona"ga mos keladimi? Qanday tuzatasiz?
Javob
Mos keladi: naqsh "^choy yoki qahva$" deb o'qiladi, choyxona esa choy bilan boshlanadi. Tuzatish — /^(?:choy|qahva)$/: endi ikkala variant ham butun matnga teng bo'lishi shart.
O'zingiz to'ldiring: faqat guruhlaydigan, lekin hech narsani ushlamaydigan qavs belgilari bilan ochiladi.
6. Qayta havola: \1 va \k<nom>
6.1 "Xuddi o'sha bo'lak yana"
Guruh topgan matnni naqshning o'zida yana ishlatish mumkin. \1 — "birinchi guruh topgan aynan o'sha matn". Bu qayta havola (backreference) deb ataladi. Xuddi hujjatdagi "yuqoridagi bilan bir xil" degan belgi kabi: o'sha joyga yangi narsa emas, oldin yozilganning aynan o'zi qo'yiladi.
Sardor sharhlarda tasodifan ikki marta yozilgan so'zlarni qidiryapti:
const sharh = "Osh juda juda mazali, choy choy ham";
console.log(sharh.match(/\b(\w+) \1\b/g));
// [ 'juda juda', 'choy choy' ](\w+) — bir so'zni ushlaydi, keyin bo'sh joy, keyin \1 — o'sha so'z yana. \w+ \w+ ikkita har qanday so'zni topardi. \1 esa ikkinchisi birinchisiga teng bo'lishini talab qiladi.
Nomlangan guruhga nom bilan murojaat qilinadi — \k<nom>:
const sharh = "Osh juda juda mazali, choy choy ham";
const naqsh = /\b(?<soz>\w+) \k<soz>\b/g;
console.log(sharh.match(naqsh)); // [ 'juda juda', 'choy choy' ]i flagi bilan qayta havola ham harf kattaligiga qaramaydi: /(\w+) \1/i naqshi Osh osh ni ham topadi.
6.2 Telefon: "hammasi bir xil"
Quantifierlar darsida telefon namunasi +99890 0000000 ni ham o'tkazib yuborgan edi: har ? alohida ishlaydi. Endi qoidani yozamiz: birinchi ajratuvchini ushlaymiz va qolganlari xuddi shunday bo'lsin.
( ?) — ixtiyoriy bo'sh joyni ushlaydi. Birinchi qatorda u bo'sh joyni ushladi — keyingi har \1 ham bo'sh joy bo'lishi shart. Ikkinchi qatorda u bo'sh matnni ushladi — keyingi \1 lar ham bo'sh. Uchinchi qator aralash, shuning uchun rad etildi. m flagi — Langarlar darsidan: ^ va $ har qatorda ishlaydi.
7. Guruhlar va metodlar
7.1 g bilan match guruhlarni yo'qotadi
RegExp asoslari darsidan eslang: g bilan match faqat matnlar massivini beradi. Guruhlar ham yo'qoladi. Har moslikning guruhlari kerak bo'lsa — matchAll:
const buyurtma = "Osh (piyozsiz), manti (5 dona), choy";
const naqsh = /\(([^)]*)\)/g;
console.log(buyurtma.match(naqsh));
console.log([...buyurtma.matchAll(naqsh)].map((m) => m[1]));Konsolda:
[ '(piyozsiz)', '(5 dona)' ]
[ 'piyozsiz', '5 dona' ]Quantifierlar darsidagi 3-mashqda qavslarni slice(1, -1) bilan kesgan edik. Endi qavslar guruhdan tashqarida, ichidagi matn esa guruhda. m[1] darhol kerakli bo'lakni beradi.
7.2 replace da $1
Almashtirish matnida $1, $2 — "shu guruh topgan matn". Bo'laklarni boshqa tartibda joylashtirish uchun eng qulay vosita:
const sana = "Bron: 2026-10-07";
console.log(sana.replace(/(\d{4})-(\d{2})-(\d{2})/, "$3.$2.$1"));
// Bron: 07.10.2026Belgilar va belgi klasslari darsida telefonni slice bilan bo'laklagan edik va "guruhlar bilan bitta replace da qilish mumkin" degan edik. Mana u:
const raqamlar = "998900000000";
const naqsh = /^998(\d{2})(\d{3})(\d{2})(\d{2})$/;
console.log(raqamlar.replace(naqsh, "+998 $1 $2 $3 $4"));
// +998 90 000 00 00Langarlar tufayli raqamlar soni noto'g'ri bo'lsa, naqsh mos kelmaydi va replace matnni o'zgartirmasdan qaytaradi.
O'zingiz to'ldiring: almashtirish matnida ikkinchi guruh topgan bo'lak deb yoziladi.
Ikki farqni eslab qoling: \1 — naqsh ichida, $1 — almashtirish matnida. $<nom> yozuvi, $& va almashtirish funksiyasiga guruhlar qanday kelishi — Almashtirish chuqur darsida.
7.3 split va guruh
Bitta kutilmagan xulq: split naqshida ushlovchi guruh bo'lsa, ajratuvchilar ham natijaga qo'shiladi:
console.log("10:00-22:00".split(/-/)); // [ '10:00', '22:00' ]
console.log("10:00-22:00".split(/(-)/)); // [ '10:00', '-', '22:00' ]Ba'zan bu kerak — masalan, matnni bo'laklab, ajratuvchini ham saqlash uchun. Kerak bo'lmasa — (?:...).
8. Yangi imkoniyat: takrorlangan nomlar (ES2025)
Sana ikki ko'rinishda kelishi mumkin: 2026-10-07 yoki 07.10.2026. Ikkalasini bitta naqsh bilan o'qish uchun | kerak. Har variantda yil, oy, kun bor — va ularga bir xil nom bergimiz keladi.
Uzoq vaqt bunday qilib bo'lmas edi. ES2025 standartida ruxsat berildi: bir nom bir nechta guruhda takrorlanishi mumkin, agar ular | ning turli variantlarida bo'lsa.
const nuqtali = /(?<kun>\d{2})\.(?<oy>\d{2})\.(?<yil>\d{4})/;
const tireli = /(?<yil>\d{4})-(?<oy>\d{2})-(?<kun>\d{2})/;
const naqsh = new RegExp(`${nuqtali.source}|${tireli.source}`);
const birinchi = "07.10.2026".match(naqsh).groups;
const ikkinchi = "2026-10-07".match(naqsh).groups;
console.log(birinchi.yil, birinchi.oy, birinchi.kun); // 2026 10 07
console.log(ikkinchi.yil, ikkinchi.oy, ikkinchi.kun); // 2026 10 07Naqsh uzun, shuning uchun uni ikki bo'lakda yozdik. Har bo'lakning source matnini (RegExp asoslari darsidan) | bilan qo'shib, bitta regex yasadik. Qaysi variant mos kelgan bo'lsa, groups.yil o'shandan olinadi. Bitta variant ichida bir nomni ikki marta yozish esa hali ham xato.
Bu imkoniyat Chrome 125, Firefox 129, Safari 17 va Node 23 dan beri bor (MDN ma'lumotlari, 2026-yil oktabr holati). Node 24 da ishlaydi. Eski brauzerlarni qo'llash kerak bo'lsa, nomlarni farqlang (yil1, yil2) — buni JS versiyalari va brauzer mosligi darsida chuqurroq ko'ramiz.
9. Ko'p uchraydigan xatolar
9.1 | ni qavssiz yozish
/^osh|manti$/ — "^osh yoki manti$". Langarlar va qo'shni bo'laklar faqat bitta variantga tegadi. Tuzatish: /^(?:osh|manti)$/.
9.2 Qisqa variantni oldinga qo'yish
/osh|oshxona/ hech qachon oshxona ni to'liq topmaydi. Tuzatish: uzunini oldinga yoki \b bilan o'rang: /\b(?:osh|oshxona)\b/.
9.3 Mos kelmagan guruh — undefined
| ning bir variantidagi guruh, boshqa variant mos kelsa, undefined bo'ladi:
const m = "soat 19:30".match(/(\d+):(\d+)|(\d+)\.(\d+)/);
console.log(m[3].padStart(2, "0"));TypeError: Cannot read properties of undefined (reading 'padStart')Tarjimasi: "undefined ning xususiyatlarini o'qib bo'lmaydi (padStart ni o'qishda)." Birinchi variant mos keldi, uchinchi guruh esa ikkinchi variantda edi — u hech narsa ushlamadi. Tuzatish: guruhni ishlatishdan oldin tekshiring (m[3] ?? m[1]) yoki takrorlangan nomli guruhlardan foydalaning.
9.4 Qavs qo'shib, raqamlarni siljitish
Naqshga (?:...) o'rniga oddiy (...) qo'shsangiz, undan keyingi guruhlarning raqami o'zgaradi. m[2] endi boshqa narsani oladi, xato esa chiqmaydi. Tuzatish: guruhlash uchun (?:...), ko'p guruhda — nomlar.
9.5 Mavjud bo'lmagan $2
console.log("ab".replace(/(a)/, "[$2]")); // [$2]bNaqshda bitta guruh bor, $2 esa yo'q guruhga ishora qiladi. JavaScript xato bermaydi — $2 ni oddiy matn sifatida qo'yadi. Tuzatish: guruhlarni sanang yoki nomlardan foydalaning.
10. Mashqlar
1-mashq (oson): Vaqtni bo'laklash
vaqtniAjrat(matn) — "19:30" kabi matndan { soat, daqiqa } obyektini qaytarsin (qiymatlar son). Shakl noto'g'ri bo'lsa — null. Nomlangan guruhlar va Number ishlating.
console.log(vaqtniAjrat("19:30")); // { soat: 19, daqiqa: 30 }
console.log(vaqtniAjrat("7:05")); // { soat: 7, daqiqa: 5 }
console.log(vaqtniAjrat("19.30")); // nullYechim
function vaqtniAjrat(matn) {
const naqsh = /^(?<soat>\d{1,2}):(?<daqiqa>\d{2})$/;
const moslik = matn.trim().match(naqsh);
if (!moslik) {
return null;
}
const { soat, daqiqa } = moslik.groups;
return { soat: Number(soat), daqiqa: Number(daqiqa) };
}
console.log(vaqtniAjrat("19:30")); // { soat: 19, daqiqa: 30 }
console.log(vaqtniAjrat("7:05")); // { soat: 7, daqiqa: 5 }
console.log(vaqtniAjrat("19.30")); // nullmatch mos kelmasa null qaytaradi — shuning uchun avval tekshirdik. Guruhlar matn beradi: "05" ni Number 5 ga aylantirdi.
2-mashq (o'rta): Taom yoki ichimlik
Buyurtma qatorlari "2 osh", "1 ko'k choy" ko'rinishida keladi. buyurtmaniOqi(qator) — { soni, nom } qaytarsin, lekin faqat menyudagi nomlar uchun: osh, manti, lag'mon, ko'k choy. Boshqa nom bo'lsa — null. Ishora: nomlarni (?<nom>osh|manti|...) bilan yozing va butun qatorni ^...$ bilan o'rang.
console.log(buyurtmaniOqi("2 osh")); // { soni: 2, nom: 'osh' }
console.log(buyurtmaniOqi("1 ko'k choy"));
// { soni: 1, nom: "ko'k choy" }
console.log(buyurtmaniOqi("3 oshxona")); // nullYechim
const naqsh =
/^(?<soni>\d+) (?<nom>osh|manti|lag'mon|ko'k choy)$/;
function buyurtmaniOqi(qator) {
const moslik = qator.trim().match(naqsh);
if (!moslik) {
return null;
}
return { soni: Number(moslik.groups.soni), nom: moslik.groups.nom };
}
console.log(buyurtmaniOqi("2 osh")); // { soni: 2, nom: 'osh' }
console.log(buyurtmaniOqi("1 ko'k choy"));
// { soni: 1, nom: "ko'k choy" }
console.log(buyurtmaniOqi("3 oshxona")); // nullAlternation guruh ichida — shuning uchun ^ va $ hamma variantga tegadi. oshxona rad etildi: osh dan keyin $ kerak edi, xona esa ortiqcha.
3-mashq (qiyin): Menyu matnidan obyektlar
Jasur aka menyuni har xil yozadi: ba'zan tire, ba'zan ikki nuqta, ba'zan so'm bilan, ba'zan usiz. menyuniOqi(matn) har qatordan { nom, narx } obyektini yasab, massiv qaytarsin. Ishora: m va g flaglari, matchAll, nomlangan guruhlar; ajratuvchi — (?: —|:), so'm — (?: so'm)?.
const menyu = `Osh — 35000 so'm
Lag'mon: 28000
Ko'k choy — 5000 so'm`;
console.log(menyuniOqi(menyu));Yechim
const menyu = `Osh — 35000 so'm
Lag'mon: 28000
Ko'k choy — 5000 so'm`;
function menyuniOqi(matn) {
const naqsh =
/^(?<nom>[\w' ]+?)(?: —|:) (?<narx>\d+)(?: so'm)?$/gm;
return [...matn.matchAll(naqsh)].map(({ groups }) => ({
nom: groups.nom,
narx: Number(groups.narx),
}));
}
console.log(menyuniOqi(menyu));Konsolda:
[
{ nom: 'Osh', narx: 35000 },
{ nom: "Lag'mon", narx: 28000 },
{ nom: "Ko'k choy", narx: 5000 }
][\w' ]+? — harf, apostrof yoki bo'sh joy, dangasa: ajratuvchidan oldingi bo'sh joyni nomga qo'shib yubormaslik uchun. Uchta ushlamaydigan guruh — ajratuvchi va ixtiyoriy so'm — natijaga hech narsa qo'shmadi. map callback'ida ({ groups }) — parametrda destructuring (Parametrda destructuring).
4-mashq: Vazifalar qadami — matndagi muddat
vazifalar foydalanuvchilari muddatni matnga yozib qo'yadi: "Hisobot topshirish 07.10.2026" yoki "Ijara to'lash 2026-10-15". Kelajakda "muddati o'tgan vazifalar" filtrini qo'shish uchun avval muddatni ajratishni o'rganamiz. kurs/mashqlar/12/05-muddat/muddat.mjs faylida muddatniOl(matn) yozing: ikki ko'rinishdan birini topib, "2026-10-07" shaklida qaytarsin, topilmasa null. Takrorlangan nomli guruhlardan foydalaning. vazifalar kodiga hozircha tegmang.
Yechim
const nuqtali = /(?<kun>\d{2})\.(?<oy>\d{2})\.(?<yil>\d{4})/;
const tireli = /(?<yil>\d{4})-(?<oy>\d{2})-(?<kun>\d{2})/;
const sanaNaqshi = new RegExp(`${nuqtali.source}|${tireli.source}`);
function muddatniOl(matn) {
const moslik = matn.match(sanaNaqshi);
if (!moslik) {
return null;
}
const { yil, oy, kun } = moslik.groups;
return `${yil}-${oy}-${kun}`;
}
const vazifalar = [
"Hisobot topshirish 07.10.2026",
"Ijara to'lash 2026-10-15",
"Non olish",
];
for (const vazifa of vazifalar) {
console.log(muddatniOl(vazifa));
}Konsolda:
2026-10-07
2026-10-15
nullBitta naqsh, ikki ko'rinish, uchta nom. Qaysi variant mos kelsa, groups o'sha variantdagi qiymatlarni oladi. "2026-10-07" shakli tasodifiy emas: bunday satrlarni oddiy < bilan solishtirsa ham sana tartibi to'g'ri chiqadi. Terminalda: node 12/05-muddat/muddat.mjs.
git add 12/05-muddat/muddat.mjs
git commit -m "12/05: muddatni nomli guruhlar bilan ajrat"11. Real ishda
- Ma'lumot ajratish. Log qatorlari, CSV, SMS matnlari ("Kartangizdan 35000 so'm yechildi") — guruhlar bilan kerakli bo'laklar bitta qadamda olinadi. Bank va to'lov xabarlarini avtomatik o'qiydigan ilovalar shunday ishlaydi.
- Marshrutlar. Sayt manzillaridagi
/menyu/12dan12ni olish — guruh. Express kabi server kutubxonalari (kursda keyin o'rganamiz) yo'llarni ichida regex guruhlariga aylantiradi. BrauzerdagiURLPatternham shunday. - Kod vositalari. Stylelint va Prettier darsidagi
/^(margin|padding|border)-(top|right|bottom|left)/qoidasini endi to'liq o'qiy olasiz: ikki guruh, ikkalasida alternation. VS Code'ning "Almashtirish" maydonida ham$1ishlaydi. - Intervyu. "Capturing va non-capturing guruh farqi?", "Backreference nima?", "Sanani
DD.MM.YYYYga aylantiring" — tez-tez beriladi.
Xulosa
( )— ushlovchi guruh: bo'lakni birlashtiradi va topilganini[1],[2]da beradi; raqam — ochuvchi qavs tartibi.- Quantifier guruhga tegadi (
(ha)+), lekin guruh faqat oxirgi takrorni eslaydi. (?:...)— faqat guruhlaydi, ushlamaydi: raqamlar siljimaydi, niyat aniq.(?<nom>...)— natijagroups.nomda; destructuring bilan qulay; ES2025 dan bir nom|ning turli variantlarida takrorlanishi mumkin.|— "yoki", eng kuchsiz belgi: deyarli har doim qavs ichida; birinchi mos kelgan variant yutadi.\1va\k<nom>— naqsh ichida "o'sha bo'lak yana";$1— almashtirish matnida.
Keyingi dars: Flaglar va lastIndex tuzog'i — sakkizta flagning hammasini ko'ramiz va g bilan test nega true, false deb "sakrashini" ochamiz.
Manbalar
- MDN: "Groups and backreferences", "Named capturing group", "Disjunction" — developer.mozilla.org
- ECMAScript 2025 Language Specification, 22.2.1 "Patterns" (Atom, GroupSpecifier, Disjunction) — tc39.es/ecma262
- TC39 taklifi: "Duplicate named capturing groups" — github.com/tc39/proposal-duplicate-named-groups
- MDN browser-compat-data 8.1.4 — takrorlangan nomli guruhlar qo'llanishi
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!