WisarWisar
Dasturlash kitobi/2-QISM — JavaScript10 daqiqa

2.13-bob: Regular expressions (RegEx)

2-QISM — JavaScript (0 dan chuqurgacha) · 13-mavzu


1. Kirish va motivatsiya

2.6-bobda matn metodlarini (slice, replace, includes) ko'rdik. Lekin ular oddiy qidiruvga yetadi. "Email to'g'rimi?", "Bu matnda barcha telefon raqamlarini top", "Faqat harf va raqamga ruxsat ber" — bunday naqsh (pattern) asosidagi vazifalar uchun Regular Expression (RegEx) kerak.

RegEx (muntazam ifoda) — matnda naqshni tasvirlovchi maxsus "til". U bilan matnni qidirish, tekshirish (validatsiya), ajratish va almashtirishni nihoyatda kuchli qilasiz.

O'xshatish: oddiy includes — "bu aniq so'z bormi?" RegEx — "raqam bilan boshlanib, @ belgisi bo'lgan, .com bilan tugagan matn bormi?" RegEx — matn uchun "aqlli filtr". Boshida g'alati ko'rinadi (/^\d{3}-\d{2}$/), lekin kuchi juda katta.

RegEx — email/telefon/parol validatsiyasi (2.12, 5.9), matndan ma'lumot ajratish, qidirish-almashtirishda ishlatiladi. U faqat JS emas — deyarli har tilda bor (universal ko'nikma).


2. Nazariya — chuqur tushuntirish

2.1. RegEx yaratish va asosiy metodlar

JS'da RegEx — /naqsh/flaglar yoki new RegExp():

js
const naqsh = /salom/i;           // literal (i = registrsiz)
const naqsh2 = new RegExp("salom", "i");  // konstruktor (dinamik bo'lsa)

// Asosiy metodlar:
naqsh.test("Salom dunyo");        // true — naqsh bormi? (boolean)
"Salom dunyo".match(naqsh);       // mos kelganlarni qaytaradi
"salom salom".replace(/salom/g, "hi");  // almashtirish (2.6)
"a,b;c".split(/[,;]/);            // ajratish (2.6)

2.2. Oddiy belgilar va metabelgilar

RegEx'da ba'zi belgilar maxsus ma'noga ega (metabelgilar):

text
.      — istalgan bitta belgi (yangi qatordan tashqari)
\d     — raqam (0–9)        \D — raqam EMAS
\w     — harf/raqam/_        \W — \w EMAS
\s     — bo'shliq (space, tab, newline)   \S — bo'shliq EMAS
\b     — so'z chegarasi
\      — keyingi maxsus belgini "oddiy" qiladi (\. = haqiqiy nuqta)
js
/\d/.test("abc5");    // true (raqam bor)
/\d\d\d/.test("123"); // true (3 raqam)

2.3. Anchors (langarlar) — joylashuv

text
^   — matn/qator BOSHi
$   — matn/qator OXIRi
\b  — so'z chegarasi (harf bilan bo'shliq/oxir orasi)
js
/^salom/.test("salom dunyo");   // true (salom bilan boshlanadi)
/dunyo$/.test("salom dunyo");   // true (dunyo bilan tugaydi)
/^\d+$/.test("12345");          // true (BUTUNLAY faqat raqam — validatsiya!)
/^\d+$/.test("123a");           // false

// \b — butun so'zni tutadi (so'z ichidagi qismni emas)
"art smart cart".match(/\bart\b/g);   // ["art"] (faqat alohida "art")

^...$ — validatsiyaning kaliti: "butun matn shu naqshga to'liq mos kelsin". ^ va $siz — faqat "ichida bormi". Validatsiyada (email, telefon) doim ^...$.

2.4. Quantifiers (miqdor) — necha marta

text
*      — 0 yoki ko'p marta
+      — 1 yoki ko'p marta
?      — 0 yoki 1 marta (ixtiyoriy)
{3}    — aniq 3 marta
{2,4}  — 2 dan 4 gacha
{2,}   — 2 yoki undan ko'p
js
/\d{3}/.test("123");      // true (aniq 3 raqam)
/\d{3,}/.test("12345");   // true (3+ raqam)
/colou?r/.test("color");  // true (u ixtiyoriy — color va colour)
/\d+/.test("a5b");        // true (1+ raqam)

Ochko'z (greedy) va dangasa (lazy): kvantorlar (*, +, ?, {n,m}) odatda ochko'z — imkon qadar ko'p belgini oladi. Orqasiga ? qo'ysangiz — dangasa bo'ladi, imkon qadar kam oladi:

text
*   +   ?   {n,m}     — ochko'z (greedy): maksimal oladi
*?  +?  ??  {n,m}?    — dangasa (lazy): minimal oladi
js
// Ochko'z: birinchi < dan oxirgi > gacha "yutib yuboradi"
"<a><b>".match(/<.+>/)[0];    // "<a><b>" (hammasini oldi!)

// Dangasa: eng yaqin > da to'xtaydi
"<a><b>".match(/<.+?>/)[0];   // "<a>" (kerakli qismgina)

Eslatma: HTML/teglar, tirnoq ichini ajratishda ochko'z naqsh ko'pincha "ortiqcha"ni oladi. Bunday joyda .+? (dangasa) yoki aniq belgilar ([^>]+) ishonchliroq.

2.5. Character classes (belgilar to'plami) [...]

text
[abc]    — a, b yoki c (bittasi)
[a-z]    — kichik harf (oraliq)
[A-Z]    — katta harf
[0-9]    — raqam (= \d)
[a-zA-Z0-9] — harf yoki raqam
[^abc]   — a, b, c'dan BOSHQA (^ ichida = inkor)
js
/[aeiou]/.test("xyz");        // false (unli yo'q)
/^[a-z0-9_]+$/.test("user_1"); // true (faqat kichik harf/raqam/_)

2.6. Groups va alternation — guruh va "yoki"

text
(...)    — guruh (ajratib olish, takrorlash uchun)
|        — yoki (alternation)
(?:...)  — guruh, lekin "eslamaydigan" (non-capturing)
js
/(ha|yoq)/.test("ha");        // true (ha YOKI yoq)
/(\d{4})-(\d{2})/.exec("2026-06");  // ["2026-06", "2026", "06"] (guruhlar)
// guruhlar — matndan qism ajratib olish uchun

2.7. Flaglar

text
g   — global (BARCHA moslikni, faqat birinchi emas)
i   — registrsiz (case-insensitive: A = a)
m   — multiline (^ va $ har qatorga)
s   — dotall (. yangi qatorni ham)
u   — unicode
js
"AaA".match(/a/g);    // ["A", "a", "A"] (g + i bilan)... aslida /a/gi
"AaA".match(/a/gi);   // ["A", "a", "A"]
"abc abc".replaceAll(/abc/g, "x");  // "x x"

2.8. Named groups va lookahead (ilg'or)

js
// Named group — guruhga nom (o'qishli)
const m = "2026-06-21".match(/(?<yil>\d{4})-(?<oy>\d{2})-(?<kun>\d{2})/);
m.groups.yil;   // "2026"
m.groups.oy;    // "06"

// Lookahead — "keyin shu kelsin/kelmasin" (tekshiradi, lekin olmaydi)
/\d+(?= so'm)/.exec("100 so'm");   // "100" (faqat "so'm" oldidagi son)
// Parol kuchi uchun ko'p ishlatiladi (5-bo'lim)

// To'rt turi (assertion — "olmaydigan" tekshiruv):
// (?=...)  oldinga, ijobiy  — keyin shu KELSIN
// (?!...)  oldinga, salbiy  — keyin shu KELMASIN
// (?<=...) orqaga, ijobiy   — oldin shu KELGAN bo'lsin
// (?<!...) orqaga, salbiy   — oldin shu KELMAGAN bo'lsin
/\d+(?!%)/.exec("50% 75");          // "5" (so'ngida % YO'Q son qismi)
/(?<=\$)\d+/.exec("$100");          // "100" ($ dan KEYINgi son, $ olinmaydi)

3. Sintaksis — tez ma'lumotnoma

text
BELGILAR:  .  \d \w \s  \D \W \S  \b (so'z chegarasi)  \. (oddiy nuqta)
LANGAR:    ^ (bosh)  $ (oxir)
MIQDOR:    *  +  ?  {3}  {2,4}  {2,}        (orqasiga ? — dangasa: *? +? ??)
TO'PLAM:   [abc]  [a-z]  [^abc]
GURUH:     (...)  |  (?:...)  (?<nom>...)
ASSERTION: (?=)  (?!)  (?<=)  (?<!)         (oldinga/orqaga look)
FLAG:      g (barcha)  i (registrsiz)  m (multiline)  s (dotall)  u  y (sticky)
js
/naqsh/flag.test(s)   s.match(re)   re.exec(s)   s.replace(re, x)   s.split(re)

4. Batafsil kod namunalari

Misol 1 — Validatsiya (^...$ bilan)

js
// Email (oddiy — real loyihada kutubxona — 5.9)
const emailRe = /^[\w.+-]+@[\w-]+\.[\w.-]+$/;
emailRe.test("ali@gmail.com");   // true
emailRe.test("ali@@x");          // false

// O'zbek telefon: +998 dan keyin 9 raqam
const telRe = /^\+998\d{9}$/;
telRe.test("+998901234567");     // true
telRe.test("998901234567");      // false (+ yo'q)

// Faqat raqam (butun matn — 2.3)
/^\d+$/.test("12345");           // true

Misol 2 — Qidirish va ajratish (2.6, 2.7)

js
const matn = "Buyurtmalar: #1024, #2048, #4096";

// Barcha buyurtma raqamlari (g flag — 2.7)
const raqamlar = matn.match(/#\d+/g);   // ["#1024", "#2048", "#4096"]

// Guruh bilan faqat sonlar (2.6)
const sonlar = [...matn.matchAll(/#(\d+)/g)].map(m => Number(m[1]));
console.log(sonlar);   // [1024, 2048, 4096]

Misol 3 — Almashtirish (2.6)

js
// Telefonni formatlash (guruhlar — 2.6)
"998901234567".replace(/(\d{3})(\d{2})(\d{3})(\d{2})(\d{2})/, "+$1 $2 $3-$4-$5");
// "+998 90 123-45-67"  ($1, $2... — guruhlar)

// Bo'shliqlarni bittaga keltirish
"salom    dunyo".replace(/\s+/g, " ");   // "salom dunyo"

// Slug (2.6 loyihasi — RegEx bilan toza)
"Salom, Dunyo!".toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
// "salom-dunyo"

Misol 4 — Parol kuchi (lookahead — 2.8)

js
// Kamida 8 belgi, 1 katta harf, 1 raqam (lookahead — 2.8)
const parolRe = /^(?=.*[A-Z])(?=.*\d).{8,}$/;
//                  ┌ katta harf bor  ┌ raqam bor  ┌ 8+ belgi
parolRe.test("Parol123");    // true
parolRe.test("parol");       // false (katta harf/raqam yo'q, qisqa)

5. To'g'ri va noto'g'ri holatlar

1) Validatsiyada ^...$ni unutish

js
//  faqat "ichida bormi" — "ali@gmail.comXXXX" ham o'tadi
/[\w]+@[\w]+\.[\w]+/.test("ali@gmail.com extra");   // true (!)

//  butun matn (2.3)
/^[\w.+-]+@[\w-]+\.[\w.-]+$/.test("ali@gmail.com");

2) Maxsus belgini "qochmaslik"

js
//  . — istalgan belgi 2.2-bob, "a@bXcom" ham o'tadi
/\w+@\w+.\w+/.test("a@bXcom");   // true (xato!)

//  \. — haqiqiy nuqta
/\w+@\w+\.\w+/.test("a@b.com");

3) Murakkab RegEx (o'qishsiz)

js
//  "yozib bo'lmaydigan" ulkan RegEx
/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+...)$/   // email RFC — dahshatli

//  murakkab validatsiya uchun kutubxona (Zod — 5.9) yoki sodda RegEx

4) g flagli RegEx'ni qayta ishlatish (lastIndex tuzog'i)

js
//  g flagli regex test()da lastIndex saqlaydi — keyingi test xato
const re = /\d/g;
re.test("1"); re.test("1");   // true, keyin false (!)

//  test/match uchun g'siz, yoki har safar yangi regex

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — RegEx "hammani" yoki "hech narsani" oladi

Sababi: . (istalgan belgi), * (0+), ^$siz. Yechimi: aniq belgilar (\d, [a-z]), ^...$, ehtiyotkor quantifier (2.2–2.4).

Xato 2 — match null qaytaradi, keyin xato

js
"abc".match(/\d+/).length;   //  null.length (mos yo'q)

Sababi: mos topilmasa match null. Yechimi: ?. 2.1-bob yoki tekshiring: const m = s.match(re); if (m) {...}.

Xato 3 — Maxsus belgi oddiy deb o'ylash

Sababi: ., *, +, (, [ maxsus 2.2-bob. Yechimi: haqiqiy belgi kerak bo'lsa \ bilan qoching (\., \*).

Xato 4 — Catastrophic backtracking (RegEx osib qoladi)

Sababi: ichma-ich (a+)+ kabi naqsh — ba'zi kiritishda eksponensial sekinlik (ReDoS — 14). Yechimi: murakkab nested quantifierdan qoching; kutubxona ishlating.

Xato 5 — Email/URL'ni RegEx bilan "mukammal" tekshirish

Sababi: to'liq email/URL RegEx — juda murakkab va baribir nomukammal. Yechimi: oddiy RegEx (Misol 1) + haqiqiy tekshiruv (tasdiqlash emaili); yoki Zod 5.9-bob.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • String metodlari 2.6-bob: replace/match/split RegEx bilan kuchayadi.
  • Validatsiya 5.9-bob: email/telefon/parol — Zod/Joi ham RegEx ishlatadi.
  • Error handling 2.12-bob: match null tekshirish.
  • Form (1.1, 11.10): input pattern atributi — RegEx.
  • Backend (5): route patternlar, ma'lumot tozalash.
  • Qidirish: matnda izlash, log tahlili.
  • Xavfsizlik (14): ReDoS, input sanitatsiya.

8. Eng yaxshi amaliyotlar (best practices)

  • Validatsiyada doim ^...$ — butun matn mos kelsin 2.3-bob.
  • Maxsus belgilarni \ bilan qoching (\., \+ — 2.2).
  • match natijasini tekshiring (null bo'lishi mumkin — 6-bo'lim).
  • RegEx'ni o'qishli tuting — murakkab bo'lsa kutubxona (Zod — 5.9) yoki izoh.
  • Named group bilan o'qishlilik ((?<yil>...) — 2.8).
  • g flag tuzog'ini eslang (lastIndex — 5-bo'lim).
  • Email/URL uchun mukammal RegEx yozmang — sodda + haqiqiy tasdiqlash (6-bo'lim).
  • RegEx test vositalaridan foydalaning (regex101.com) — sinash va tushunish uchun.

9. Amaliy loyiha: "Matn Tahlil va Validatsiya Quroli"

RegEx'ni amalda mustahkamlovchi loyiha.

Maqsad

RegEx bilan validatsiya, qidirish, ajratish va almashtirishni amalda qo'llab, matn bilan ishlash quvvatini oshirish.

Talablar (requirements)

  1. Validatorlar (^...$ bilan): email, o'zbek telefon (+998XXXXXXXXX), parol (8+ belgi, katta harf, raqam — Misol 4), foydalanuvchi nomi (faqat harf/raqam/_, 3–16 belgi).
  2. Ajratuvchi: matndan barcha email/telefon/hashtag (#soz)ni matchAll bilan ajrating (Misol 2).
  3. Formatlovchi: telefonni chiroyli formatga (+998 90 123-45-67 — Misol 3), sanani (2026-06-21 21.06.2026) almashtiring.
  4. Tozalovchi: ortiqcha bo'shliqlarni bittaga, slug yaratish (Misol 3).
  5. Hisoblovchi: matndagi so'z soni, raqam soni, eng uzun so'zni toping (match + Array metodlari — 2.7).
  6. Maskalovchi: kredit karta/telefonni yashiring (5614 **** **** 1234).
  7. Har validator chegaraviy holat (bo'sh, noto'g'ri format) bilan sinasin 0.6-bob; match null tekshirilsin (6-bo'lim).

Maslahatlar (hint)

  • Validatsiyada ^...$ shart 2.3-bob.
  • Telefon format: guruhlar + $1 $2... (Misol 3).
  • matchAll g flag bilan, [...] (spread) yoki Array.from bilan massivga 2.7-bob.
  • regex101.com'da naqshlarni sinab ko'ring.
  • Maxsus belgi (.) — \. 2.2-bob.
  • g flagli regex'ni testda qayta ishlatmang (5-bo'lim).

"Tayyor" mezonlari (acceptance criteria)

  • Barcha validatorlar ^...$ bilan, to'g'ri/noto'g'ri holatda ishlaydi.
  • Ajratuvchi barcha moslikni (g flag) topadi.
  • Telefon/sana formatlovchi guruhlar bilan ishlaydi.
  • Slug/tozalovchi to'g'ri natija beradi.
  • Hisoblovchi so'z/raqam sonini to'g'ri beradi.
  • match null holati ushlangan.
  • Maxsus belgilar to'g'ri "qochirilgan".

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda matn naqshlari qurolini — RegExni o'rgandik:

  • RegEx — /naqsh/flag; metodlar: test (bormi), match/matchAll (top), replace (almashtir), split (ajrat).
  • Belgilar: . \d \w \s; langar: ^ $ (validatsiya kaliti); miqdor: * + ? {n}; to'plam: [a-z]; guruh: (...) |; flag: g i m.
  • Ilg'or: named group (?<nom>), lookahead/lookbehind (?=) (?!) (?<=) (?<!), dangasa kvantor .+? (2.4, 2.8).
  • Tuzoqlar: ^...$siz validatsiya, maxsus belgini qochmaslik, match null, g lastIndex, ReDoS.

Keyingi bob — 2.14-bob: Modullar — ES Modules (import/export), CommonJS. Hozirgacha kodni bitta faylda yozdik; lekin real loyiha ko'p fayldan iborat. Modullar — kodni fayllarga bo'lib, import/export bilan bog'lashning usuli. Bu — har bir Node (5) va React (11) loyihasining asosiy tuzilishi (0.7'dagi package.jsonni esla).


Foydalanilgan rasmiy/ishonchli manbalar

  • MDN Web Docs — Regular expressions, RegExp, character classes, quantifiers
  • MDN Web Docs — groups, assertions (lookahead), named groups, flags
  • regex101.com — RegEx sinash va tushuntirish vositasi

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
2.13-bob: Regular expressions (RegEx) — Wisar