IlmHamroh
JavaScript Full-stack/12-qism. JavaScript: ilg'or mavzular va kod sifati2/44-dars18 daqiqa
Mundarija (39)

Regex belgilari va belgi klasslari: \d, \w, \s va [...]

Qisqacha: Regex'da oddiy belgi o'zini bildiradi, metabelgi (. + * ? ^ $ ( ) [ ] { } | \) esa buyruq. Metabelgining o'zi kerak bo'lsa, oldiga \ qo'yiladi: \+998. \d — raqam, \w — lotin harf, raqam yoki _, \s — bo'sh joy; katta harfi (\D, \W, \S) — teskarisi. [...] — "shu belgilardan biri": [.,], [0-9], [a-z]. [^...] — "shulardan boshqa har qanday".

Bu darsda

  • Qaysi belgilar regex'da maxsus ekanini bilasiz va ularni \ bilan oddiy belgiga aylantirasiz.
  • \d, \w, \s va ularning teskarisi \D, \W, \S bilan belgilar guruhini bitta belgi bilan yozasiz.
  • \w o'zbekcha so'm so'zini nega ikkiga bo'lishini tushuntira olasiz va buni tuzatasiz.
  • [...], diapazon [a-z] va inkor klass [^...] bilan o'z belgi to'plamingizni yasaysiz.
  • Telefon raqamini \D bilan bir qatorda tozalaysiz.

Oldin bilishingiz kerak: RegExp asoslari va metodlari, String asoslari, Unicode va emoji.

1. Nega bu kerak?

O'tgan darsda Sardor ikki marta qoqildi. Birinchisi — new RegExp("+998") xato berdi. Ikkinchisi — narxni /5.000/ bilan qidirganida, u 52000 ni ham topdi. Ikkalasining sababi bitta: regex'da ba'zi belgilar o'zini emas, buyruqni bildiradi. Ularni bilmasangiz, regex siz kutmagan narsani qiladi.

Endi yangi vazifa. «Bahor»ning ish vaqti saytda turli joyda har xil yozilgan: 07:00, 23.00, 22-00. Jasur aka so'radi: "Ikki nuqta yoki nuqta bilan yozilgan vaqtlarni top". O'tgan darsdagi belgilar bu yerda yetmaydi. Bizga "ikki nuqta yoki nuqta" — ya'ni "shu ikki belgidan biri" degan yozuv kerak.

Bugun ikki narsani o'rganamiz:

  1. Qaysi belgilar maxsus va ularni qanday "o'chirish".
  2. Belgilar to'plamini — "har qanday raqam", "shu uchta belgidan biri", "harfdan boshqa hamma narsa" — qanday yozish.

2. Oddiy belgilar va metabelgilar

2.1 Ikki xil belgi

Regex'dagi har bir belgi ikki turdan biri:

  • Oddiy belgi — o'zini bildiradi. o, s, 7, :, bo'sh joy — /o's/ aynan o's ni qidiradi.
  • Metabelgi (metacharacter) — maxsus ma'noli belgi. U matndagi o'zini emas, qoidani bildiradi. "Meta" — "ustida, haqida" degani: bu belgilar matn haqida gapiradi.

JavaScript regex'idagi metabelgilar:

Belgi Ma'nosi Qayerda o'rganamiz
\ escape: keyingi belgining ma'nosini o'zgartiradi shu dars
. istalgan bitta belgi shu dars
[ ] belgi klassi shu dars
^ $ boshi va oxiri Langarlar
* + ? { } takrorlash Quantifierlar
( ) | guruh va "yoki" Guruhlar

Literal regex'da yana / ham maxsus: u regex'ning chegarasi. Uni naqsh ichida yozish uchun ham \ kerak: sanadagi 05/10 uchun /\d\d\/\d\d/.

Ro'yxatni yodlash shart emas. Bitta qoidani eslab qoling: harf, raqam, bo'sh joy, :, -, ,, ', @ — oddiy. Qolgan tinish belgilari — ehtimol maxsus. Shubha bo'lsa — \ qo'ying yoki maydonda sinang.

2.2 Escape: \ bilan "o'chirish"

Escape (ekranlash) — metabelgi oldiga \ qo'yib, uni oddiy belgiga aylantirish. Xuddi "STOP" yozuvi kabi: yo'l chetidagi belgida u buyruq, gazetadagi maqolada esa shunchaki to'rt harf. \ regex'ga "bu buyruq emas, shunchaki belgi" deydi. \+ — "plyus belgisining o'zi", \. — "nuqtaning o'zi", \( — "qavsning o'zi".

Maydondan \ ni o'chirsangiz, o'tgan darsdagi Nothing to repeat xatosi chiqadi. Plyus "oldingisini takrorla" deb tushuniladi, oldida esa hech narsa yo'q.

\ ning o'zi ham metabelgi. Matndagi teskari chiziqni qidirish uchun uni ikki marta yozasiz: /\\/ — "bitta teskari chiziq". Windows'dagi C:\Bahor kabi yo'llarda kerak bo'ladi.

E'tibor bering: \ ikki yo'nalishda ishlaydi. Metabelgi oldida u ma'noni o'chiradi (\. — oddiy nuqta). Ba'zi oddiy harflar oldida esa ma'no beradi: d — oddiy harf, \d — "har qanday raqam". Keyingi bo'lim shu harflar haqida.

2.3 Nuqta: istalgan belgi

. — istalgan bitta belgi. Bitta istisno — yangi qator belgisi (\n). Uni ham qamrash uchun s flagi bor, Flaglar darsida ko'ramiz.

Nuqta qulay, lekin "hamma narsa" ko'pincha ortiqcha. Narx misoli:

js
const matn = "5.000 52000 5 000";

console.log(matn.match(/5.000/g)); // [ '5.000', '52000', '5 000' ]
console.log(matn.match(/5\.000/g)); // [ '5.000' ]

Escape qilinmagan nuqta 2 ni ham, bo'sh joyni ham qabul qildi. Narxning aynan nuqtali yozuvi kerak bo'lsa — \..

Tekshirib ko'ring: /a.b/ naqshi "a.b", "a-b" va "ab" dan qaysilariga mos keladi?

Javob

"a.b" va "a-b" ga. Nuqta istalgan bitta belgini talab qiladi — . ham, - ham bo'laveradi. "ab" da a va b orasida hech qanday belgi yo'q, shuning uchun mos kelmaydi.

3. Tayyor klasslar: \d, \w, \s

3.1 Uchta qisqa yozuv

Belgi klassi (character class) — bitta o'rinda turishi mumkin bo'lgan belgilar to'plami. Test savolidagi javob variantlariga o'xshaydi: variant ko'p, lekin katakka faqat bittasi yoziladi. Regex'da uchta tayyor klass bor:

Klass Ma'nosi Teng
\d raqam (digit) [0-9]
\w "so'z belgisi" (word): lotin harf, raqam, _ [A-Za-z0-9_]
\s bo'sh joy (space): oddiy bo'sh joy, \t, \n, \u00a0 va boshqalar —

\d ni o'tgan darsdan bilasiz. \s ham tanish: u "Ali Valiyev" dagi bo'sh joylarni ham, uzilmas bo'sh joyni ham ushladi. Uchinchi ustundagi [0-9] kabi yozuvni birozdan keyin o'rganamiz.

Maslahat: \d faqat oddiy 0–9 raqamlarini taniydi. Arab yozuvidagi ١٢ kabi raqamlar unga kirmaydi — hatto u flagi bilan ham. Bu ko'pincha yaxshi: telefon va narx maydonida faqat oddiy raqam bo'lishi kerak.

3.2 \w va o'zbek apostrofi

\w nomi "word" (so'z) bo'lsa ham, u o'zbekcha so'zni to'liq tanimaydi. Maydonga qarang:

Ko'k — Ko va k, so'm — so va m. Sababi: \w faqat A–Z, a–z, 0–9 va _ dan iborat. Apostrof ' unga kirmaydi. Kirill harflari ham kirmaydi — ruscha Ош so'zi \w uchun "so'z" emas.

Bu o'zbek dasturchisi uchun eng muhim tuzoq. o', g' bor har bir so'z — o'rik, g'isht, bo'lim — \w+ bilan bo'linib ketadi. Yechimi — o'z klassingizni yasash: [\w'], ya'ni "so'z belgisi yoki apostrof". Uni keyingi bo'limda ko'ramiz. Har qanday tildagi harfni taniydigan \p{L} esa Unicode regex: u va v flag darsida.

3.3 \s ichida nima bor

Bo'sh joy faqat Space tugmasi qo'yadigan belgi emas. Klaviaturadagi Tab tugmasi \t belgisini qo'yadi, Enter esa yangi qator — \n. Windows'da yangi qator ikki belgidan iborat: \r\n. Yana uzilmas bo'sh joy bor — u saytdan nusxalangan narxlarda ko'p uchraydi. \s bularning hammasini taniydi.

Bu amalda qachon kerak? Jasur aka Excel jadvalidan menyuni nusxalab, formaga qo'ydi. Ustunlar orasida oddiy bo'sh joy emas, \t turibdi:

js
const qator = "Osh\t35000\tasosiy";

console.log(qator.split(" ")); // [ 'Osh\t35000\tasosiy' ]
console.log(qator.split(/\s/)); // [ 'Osh', '35000', 'asosiy' ]

split(" ") hech narsani bo'lmadi — matnda birorta ham oddiy bo'sh joy (" ") yo'q. split(/\s/) esa tabulyatsiyani ham bo'sh joy deb tanidi. Foydalanuvchidan keladigan matnda "bo'sh joy" deganda deyarli har doim \s ni nazarda tutasiz.

Tekshirib ko'ring: "Osh\nManti".match(/\s/g) nima qaytaradi?

Javob

[ '\n' ] — bitta moslik, yangi qator belgisi. Node uni ko'rinadigan qilib '\n' deb yozadi. \s yangi qatorni ham bo'sh joy deb hisoblaydi.

3.4 Katta harf — teskarisi

Har klassning katta harfli egizagi bor. U "shulardan boshqa har qanday belgi" degani:

Klass Ma'nosi
\D raqam bo'lmagan har qanday belgi
\W \w ga kirmaydigan har qanday belgi (bo'sh joy, tinish belgisi, apostrof, kirill harfi)
\S bo'sh joy bo'lmagan har qanday belgi

Eng foydalisi — \D. Telefon raqami har xil yozilsa ham, ichidagi raqamlarni bitta qatorda ajratadi:

js
const tel = "+998 (90) 000-00-00";

console.log(tel.replace(/\D/g, "")); // 998900000000

"Raqam bo'lmagan hamma narsani o'chir" — plyus, bo'sh joy, qavs, tire bir zarbada ketdi. SMS xizmatlari raqamni aynan shu ko'rinishda kutadi.

\S+ esa "bo'sh joysiz bo'lak" — so'zlarni bo'sh joylar orasidan ajratadi:

js
console.log("Ali   Valiyev".match(/\S+/g)); // [ 'Ali', 'Valiyev' ]

Tekshirib ko'ring: "Narx: 35 000 so'm".replace(/\D/g, "") nima qaytaradi?

Javob

"35000". Raqam bo'lmagan hamma narsa — Narx:, bo'sh joylar, so'm — olib tashlandi. Natija satr, son kerak bo'lsa Number bilan o'raysiz.

4. O'z klassingiz: [...]

4.1 "Shu belgilardan biri"

Kvadrat qavs ichidagi belgilar — bitta o'rin uchun variantlar ro'yxati. [.:] — "nuqta yoki ikki nuqta". [aou] — "a, o yoki u".

Endi «Nega bu kerak?» bo'limidagi vazifani yechamiz: 07:00 va 23.00 ni topamiz, 22-00 ni esa yo'q.

Naqshni o'qiymiz: ikki raqam, keyin nuqta yoki ikki nuqta, keyin yana ikki raqam. 22-00 dagi tire klassda yo'q — mos kelmadi.

E'tibor bering: [.:] ichida nuqtani escape qilmadik. Klass ichida ko'p metabelgilar o'z kuchini yo'qotadi — [.] oddiy nuqta, [+] oddiy plyus. Klass ichida faqat to'rtta belgi maxsus:

  • \ — escape ([\d.] — raqam yoki nuqta);
  • ] — klassni yopadi (o'zi kerak bo'lsa: [\]]);
  • ^ — faqat birinchi o'rinda (inkor klass, birozdan keyin);
  • - — ikki belgi orasida (diapazon, keyingi bo'lim).

4.2 Klass — bitta belgi

Boshlovchilar tez-tez [osh] ni "osh so'zi" deb o'ylaydi. Yo'q. Klass har doim bitta belgini tanlaydi:

js
console.log("osh shox".match(/[osh]/g));

Konsolda:

text
[ 'o', 's', 'h', 's', 'h', 'o' ]

Har moslik — bitta harf: o, s yoki h. x va bo'sh joy klassda yo'q. "osh" so'zini qidirish uchun klass kerak emas — shunchaki /osh/.

4.3 Tayyor klasslarni birlashtirish

\d, \w, \s ni klass ichiga qo'yish mumkin. Shunda ular boshqa belgilar bilan birlashadi. Endi \w muammosining yechimi:

js
const matn = "Ko'k choy — 5000 so'm";

console.log(matn.match(/[\w']+/g));

Konsolda:

text
[ "Ko'k", 'choy', '5000', "so'm" ]

[\w'] — "so'z belgisi yoki apostrof". + bilan — "shulardan bir yoki ko'p". Ko'k va so'm butun qoldi. Node apostrofli satrni qo'shtirnoq bilan chiqardi — satr ichidagi ' bilan chalkashmasin deb.

Yana bir misol — email'ning @ dan oldingi qismi. Unda harf, raqam va nuqta bo'ladi:

js
const matn = "Yozing: ali.valiyev@example.com";

console.log(matn.match(/[\w.]+@example\.com/)[0]);
// ali.valiyev@example.com

[\w.]+ — "so'z belgisi yoki nuqtadan iborat bo'lak". Klass ichidagi . — oddiy nuqta. Klassdan tashqaridagi \. ham oddiy nuqta, lekin u yerda escape shart.

Tekshirib ko'ring: /[+\d]+/g naqshi "+998 90" matnida nimani topadi?

Javob

[ '+998', '90' ]. Klass ichida + oddiy belgi, shuning uchun "plyus yoki raqam"dan iborat bo'laklar topildi. Bo'sh joy klassda yo'q — u ikki moslikni ajratib turdi. Klassdan keyingi + esa haqiqiy quantifier: "bir yoki ko'p".

5. Diapazon: [a-z], [0-9]

5.1 Chiziqcha bilan oraliq

Hamma harfni sanab chiqish noqulay: [abcdefghijklmnopqrstuvwxyz]. Buning o'rniga diapazon (range) yoziladi: ikki belgi orasiga -. [a-z] — "a dan z gacha istalgan kichik harf".

Yozuv Ma'nosi
[0-9] istalgan raqam (\d bilan bir xil)
[a-z] kichik lotin harf
[A-Z] katta lotin harf
[A-Za-z] istalgan lotin harf
[0-5] 0 dan 5 gacha raqam

Bitta klassda bir nechta diapazon va oddiy belgilar aralashib turishi mumkin: [A-Za-z'] — "lotin harf yoki apostrof".

O'zingiz to'ldiring: [0-9] diapazonining qisqa, tayyor yozuvi — .

5.2 Vaqt uchun diapazon

Daqiqa 00 dan 59 gacha bo'ladi — birinchi raqami 5 dan katta emas. Soatning birinchi raqami esa 0, 1 yoki 2:

07:75 va 39:10 chiqib ketdi. Lekin bu naqsh 29:00 ni hali ham qabul qiladi — soatning ikkinchi raqami birinchisiga bog'liq (2 dan keyin faqat 0–3). Bunday "yoki"li shartni Guruhlar va alternation darsida yozamiz.

5.3 Diapazon belgi tartibi bo'yicha

Diapazon kompyuterdagi belgilar tartibiga qaraydi — har belgining raqamli kodi bor (Unicode va emoji darsidan). [a-z] — kodi a niki va z niki orasidagi hamma belgi. Ikki tuzoq shundan kelib chiqadi.

Birinchisi — teskari tartib xato beradi:

js
const naqsh = new RegExp("[z-a]");
text
SyntaxError: Invalid regular expression: /[z-a]/: Range out of order in character class

Tarjimasi: "Belgi klassida diapazon tartibi buzilgan." z ning kodi a nikidan katta. Diapazon har doim kichikdan kattaga yoziladi.

Ikkinchisi — [A-z]. U "hamma lotin harflar"ga o'xshaydi, lekin katta va kichik harflar orasida yana oltita belgi bor: [, \, ], ^, _ va teskari tirnoq:

js
console.log(/[A-z]/.test("_")); // true
console.log(/[A-z]/.test("^")); // true

To'g'risi — [A-Za-z].

5.4 Chiziqchaning o'zi

- klassning boshida yoki oxirida tursa — oddiy chiziqcha. O'rtada tursa — diapazon:

js
console.log("a-b_c".match(/[a-c-]/g)); // [ 'a', '-', 'b', 'c' ]

[a-c-] — "a dan c gacha yoki chiziqcha". Telefon tozalashda [ ()-] kabi klass yozsangiz, - ni oxiriga qo'ying.

5.5 Eski tanish: grep "[0-9]"

Fayl va matn qidirish darsida terminalda grep -rn "[0-9]" src deb yozgan edik va u raqami bor qatorlarni topgan edi. Endi bu yozuvni to'liq o'qiy olasiz: [0-9] — "istalgan bitta raqam" diapazoni. JavaScript'da xuddi shu naqsh /[0-9]/ yoki qisqasi /\d/.

grep, VS Code qidiruvi, ESLint qoidalari va JavaScript regex'i — har biri o'z "lahjasi"da gapiradi, lekin klasslar, diapazonlar va escape hamma joyda bir xil ishlaydi. Farqlar asosan murakkab qismlarda: masalan, oddiy grep \d ni tanimaydi, unga [0-9] yoki grep -P ("Perl uslubi") kerak. Shuning uchun diapazon yozuvini bilish foydali — u deyarli hamma vositada tushuniladi.

Tekshirib ko'ring: [0-9A-F] qanday belgilarni qabul qiladi? U qayerda kerak bo'lishi mumkin?

Javob

Raqamlar va A dan F gacha katta harflar — o'n oltilik sanoq tizimining raqamlari (Son yozish shakllari darsidan). CSS ranglari (#1A2B3C) shunday belgilardan iborat. Kichik harfli #1a2b3c ham bo'lishi mumkin — unda klass [0-9A-Fa-f] bo'ladi.

6. Inkor klass: [^...]

6.1 "Shulardan boshqa"

Klassning birinchi belgisi ^ bo'lsa, ma'no teskariga aylanadi: "ro'yxatdagi belgilardan boshqa har qanday bitta belgi". Bu inkor klass (negated class).

\D aslida [^0-9] ning qisqa yozuvi. O'zingiz ham shunday klass yasashingiz mumkin:

Klassda \d va bo'sh joy bor, ^ ularni teskariga aylantirdi. Natijada so'zlar topildi — so'm dagi apostrof va undan keyingi vergul bilan birga.

6.2 Ruxsat etilmagan belgini topish

Inkor klassning eng foydali ishlatilishi — "ruxsat etilmagan belgi bormi?" degan savol. Bron formasida ism faqat lotin harflari, apostrof va bo'sh joydan iborat bo'lishi kerak:

js
const begona = /[^A-Za-z' ]/;

console.log(begona.test("Dilshod aka")); // false
console.log(begona.test("G'ayrat")); // false
console.log(begona.test("Dilshod2")); // true

true — "ruxsat etilmagan belgi topildi". Dilshod2 dagi 2 klassga kirmaydi, demak u begona. Ismni tekshirish uchun natijani teskariga aylantirasiz: !begona.test(ism).

Bu usul "matn faqat shu belgilardan iborat" degan qoidani langarlarsiz yozish imkonini beradi. Langarlar bilan qisqaroq yo'lini keyingi darsda ko'ramiz.

6.3 ^ ning ikki ma'nosi

^ faqat klassning birinchi belgisi bo'lganda inkor qiladi. Boshqa joyda — oddiy belgi: [a^] — "a yoki ^". Klassdan tashqarida esa ^ butunlay boshqa narsa — matn boshi. Bu keyingi darsning mavzusi. Hozircha eslab qoling: [^a] va ^a — ikki xil narsa.

Yana bir farq: inkor klass yangi qator belgisini ham qabul qiladi. . esa qabul qilmaydi. [^x] — "x dan boshqa har qanday", \n ham shu jumladan.

Tekshirib ko'ring: "Narx: 35 000 so'm".replace(/[^\d]/g, "") va "Narx: 35 000 so'm".replace(/\D/g, "") farq qiladimi?

Javob

Yo'q, ikkalasi ham "35000". [^\d] — "raqamdan boshqa", ya'ni \D ning o'zi. Odatda qisqaroq \D yoziladi.

O'zingiz to'ldiring: "raqam ham, harf ham, _ ham bo'lmagan belgi" ni qisqa klass bilan deb yozasiz.

7. Ko'p uchraydigan xatolar

7.1 Metabelgini escape qilmaslik

/5.000/ 52000 ga, /www.example.com/ esa wwwXexample.com ga ham mos keladi. Tekshiruv naqshida bu xavfli: soxta qiymat o'tib ketadi. Tuzatish: matndagi nuqta, plyus, qavs — \., \+, \(.

7.2 \w ni "har qanday harf" deb o'ylash

/\w+/ bilan o'zbekcha so'zlarni sanasangiz, so'm ikki so'z bo'ladi, G'ayrat esa G va ayrat. Ruscha ism esa umuman topilmaydi. Tuzatish: o'zbekcha lotin matn uchun [\w'] yoki [A-Za-z']. Har qanday til uchun — \p{L} (Unicode regex).

7.3 [A-z]

U oltita ortiqcha belgini qabul qiladi, shu jumladan _ va ^. Tuzatish: [A-Za-z].

7.4 Klassni so'z deb o'ylash

[osh] — o, s yoki h dan bittasi. [^osh] ham "osh so'zidan boshqa" emas — "o, s, h dan boshqa bitta belgi". So'zni inkor qilish uchun boshqa vosita kerak — Lookahead va lookbehind darsida.

7.5 Satrda ikki marta escape

new RegExp("[\d.]+") — satr \d dagi \ ni yutadi, klass [d.] bo'lib qoladi. Tuzatish: new RegExp("[\\d.]+"). JSON fayllarda (masalan, sozlama faylidagi naqsh) ham xuddi shunday: "\\d".

8. Mashqlar

1-mashq (oson): Faqat raqamlar

raqamlarniOl(tel) funksiyasi telefon yozuvidan faqat raqamlarni qoldirsin. \D dan foydalaning.

js
console.log(raqamlarniOl("+998 (90) 000-00-00")); // 998900000000
console.log(raqamlarniOl("90 000 00 00")); // 900000000
Yechim
js
function raqamlarniOl(tel) {
  return tel.replace(/\D/g, "");
}

console.log(raqamlarniOl("+998 (90) 000-00-00")); // 998900000000
console.log(raqamlarniOl("90 000 00 00")); // 900000000

g muhim: usiz faqat birinchi raqamsiz belgi — + — o'chardi.

2-mashq (o'rta): Ism to'g'rimi?

ismTogrimi(ism) — ism bo'sh bo'lmasa va faqat lotin harflari, apostrof va bo'sh joydan iborat bo'lsa true qaytarsin. Ishora: inkor klass bilan "begona belgi bormi?" deb so'rang va natijani ! bilan teskariga aylantiring.

js
console.log(ismTogrimi("G'ayrat")); // true
console.log(ismTogrimi("Ali2")); // false
console.log(ismTogrimi("")); // false
Yechim
js
function ismTogrimi(ism) {
  return ism.length > 0 && !/[^A-Za-z' ]/.test(ism);
}

console.log(ismTogrimi("G'ayrat")); // true
console.log(ismTogrimi("Ali2")); // false
console.log(ismTogrimi("")); // false

Bo'sh satrda begona belgi yo'q — !test true berardi. Shuning uchun ism.length > 0 sharti alohida kerak. Keyingi darsda langarlar bilan bu ikkalasini bitta naqshga yig'amiz.

3-mashq (qiyin): Telefonni bir xil ko'rinishga keltirish

telefonniFormatla(tel) har qanday yozuvdagi o'zbek raqamini +998 90 000 00 00 ko'rinishiga keltirsin. Kirish 998 bilan yoki usiz bo'lishi mumkin. Ishora: avval \D bilan tozalang; 9 ta raqam qolsa, oldiga 998 qo'shing; keyin slice bilan bo'laklang (Kesish, bo'lish va to'ldirish).

js
console.log(telefonniFormatla("(90) 000-00-00"));
console.log(telefonniFormatla("+998900000000"));
// ikkalasi ham: +998 90 000 00 00
Yechim
js
function telefonniFormatla(tel) {
  let r = tel.replace(/\D/g, "");
  if (r.length === 9) {
    r = "998" + r;
  }
  return `+${r.slice(0, 3)} ${r.slice(3, 5)} ${r.slice(5, 8)} ` +
    `${r.slice(8, 10)} ${r.slice(10, 12)}`;
}

console.log(telefonniFormatla("(90) 000-00-00"));
console.log(telefonniFormatla("+998900000000"));

Konsolda:

text
+998 90 000 00 00
+998 90 000 00 00

Regex faqat tozalash uchun kerak bo'ldi. Bo'laklash — oddiy slice. Guruhlar bilan buni bitta replace da qilish mumkin — Guruhlar va alternation darsida ko'ramiz. Raqam soni noto'g'ri bo'lsa, bu funksiya g'alati natija beradi — tekshiruvni keyingi darsda qo'shamiz.

4-mashq: Vazifalar qadami — teglar va tinish belgilari

vazifalar dagi royxat.js da teglar shunday ajratiladi: matn.toLowerCase().split(" ") va # bilan boshlanganlari olinadi. Sinab ko'ring: "Non olish #bozor, #tez" matnidan qanday teglar chiqadi? kurs/mashqlar/12/02-teglar/teglar.mjs da ikki usulni solishtiring: eski (split) va regex ([\w'] klassi bilan). vazifalar kodini hozircha o'zgartirmang.

Yechim
js
const matn = "Non olish #bozor, #tez #do'kon";

const eski = matn
  .toLowerCase()
  .split(" ")
  .filter((soz) => soz.length > 1 && soz.startsWith("#"));
const yangi = matn.toLowerCase().match(/#[\w']+/g) ?? [];

console.log(eski);
console.log(yangi);

Konsolda:

text
[ '#bozor,', '#tez', "#do'kon" ]
[ '#bozor', '#tez', "#do'kon" ]

Eski usulda vergul tegga yopishib qoldi: #bozor, va #bozor ikki xil teg bo'lib ketadi. Regex # dan keyin faqat so'z belgilari va apostrofni oladi — vergul klassga kirmaydi. [\w'] o'rniga \w+ yozsak, #do'kon #do bo'lib qolardi.

bash
git add 12/02-teglar/teglar.mjs
git commit -m "12/02: teglarni regex klassi bilan ajratish"

9. Real ishda

  • Ma'lumot tozalash. replace(/\D/g, "") — telefon, karta raqami, INN, pochta indeksi bilan ishlaydigan har bir loyihada bor. Click va Payme kabi to'lov tizimlariga raqam faqat raqamlar ko'rinishida yuboriladi.
  • Tekshiruv. Login, promo-kod, mahsulot artikuli kabi maydonlar "faqat shu belgilar" qoidasi bilan tekshiriladi: [A-Za-z0-9_] yoki [A-Z0-9-].
  • O'zbek tili. Apostrof (') va uning "chiroyli" variantlari (ʻ, ’) bilan ishlash — mahalliy loyihalarda doimiy masala. \w ga ishonib yozilgan qidiruv o' li so'zlarni buzadi. Buni Unicode regex darsida chuqurroq ko'ramiz.
  • Intervyu. "\w nimaga mos keladi?", "[^...] va ^ farqi?", "Nuqtani qanday qidirasiz?" — tez-tez so'raladi.

Xulosa

  • Metabelgilar — \ . [ ] ^ $ * + ? { } ( ) | (literalda / ham); ularning o'zi kerak bo'lsa — \ bilan escape.
  • . — istalgan bitta belgi (\n dan tashqari); nuqtaning o'zi — \..
  • \d — raqam, \w — [A-Za-z0-9_], \s — bo'sh joy; \D, \W, \S — teskarisi.
  • \w apostrofni va kirillni tanimaydi: o'zbekcha so'z uchun [\w'].
  • [...] — bitta o'rin uchun variantlar; ichida faqat \ ] ^ - maxsus; diapazon [a-z] kichikdan kattaga, [A-z] emas, [A-Za-z].
  • [^...] — "shulardan boshqa har qanday belgi"; ^ faqat birinchi o'rinda inkor qiladi.

Keyingi dars: Langarlar va so'z chegarasi — ^, $ va \b bilan moslik qayerda bo'lishini belgilaymiz va "matn faqat shundan iborat" degan tekshiruvni bitta naqsh bilan yozamiz.

Manbalar

  • MDN: "Character classes", "Character escape", "Character class escape" (Regular expressions guide) — developer.mozilla.org
  • ECMAScript 2025 Language Specification, 22.2.2 "Pattern Semantics" (CharacterClassEscape) — tc39.es/ecma262
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Regex belgilari va belgi klasslari: \d, \w, \s va [...] — IlmHamroh