Go’da regular expression bilan ishlash
Regular expression, qisqacha regex, matndagi takrorlanuvchi shaklni ifodalovchi shablondir. U matndan qiymat qidirish, formatni tekshirish, qismlarga ajratish va mos joylarni almashtirishda ishlatiladi.
Masalan, log satrlaridan sana topish, foydalanuvchi nomi formatini tekshirish yoki matndagi ortiqcha bo‘sh joylarni almashtirish mumkin. Regex aniq matnni emas, matnning qanday tuzilishini yozadi.
Regex barcha matn vazifalari uchun kerak emas. Aniq substring uchun strings.Contains(), prefiks uchun strings.HasPrefix(), URL uchun net/url, vaqt uchun time.Parse() ko‘pincha sodda va ishonchliroq.
Birinchi shablon
Quyidagi matndan YYYY-MM-DD ko‘rinishidagi qismni topamiz:
Shablon:
Bu yerda:
\d— ASCII raqam, ya’ni0dan9gacha;{4}— oldingi element aynan to‘rt marta;-— oddiy tire belgisi;{2}— oldingi element aynan ikki marta.
Shablon sana ko‘rinishini topadi, lekin qiymat haqiqiy sana ekanini isbotlamaydi. Masalan, 9999-99-99 ham shu regexga mos keladi. Haqiqiy sanani tekshirish uchun topilgan satrni time.Parse("2006-01-02", value) bilan parse qilish kerak.
Asosiy belgilar
| Belgi | Ma’nosi | Misol | Mos qiymat |
|---|---|---|---|
. |
Yangi qatordan boshqa bitta belgi | c.t |
cat, cut |
\d |
ASCII raqam | \d{2} |
12 |
\w |
ASCII harf, raqam yoki _ |
\w+ |
go_123 |
\s |
Bo‘sh joy belgisi | a\s+b |
a b, a\tb |
+ |
Bir yoki ko‘p marta | a+ |
a, aaa |
* |
Nol yoki ko‘p marta | ba* |
b, baa |
? |
Nol yoki bir marta | colou?r |
color, colour |
{n} |
Aynan n marta |
\d{4} |
2025 |
{n,m} |
ndan mgacha |
\d{2,4} |
12, 2025 |
^ |
Matn boshi | ^salom |
boshidagi salom |
$ |
Matn oxiri | dunyo$ |
oxiridagi dunyo |
[abc] |
To‘plamdagi bitta belgi | [abc] |
a, b yoki c |
[^0-9] |
To‘plamga kirmaydigan belgi | [^0-9] |
raqamdan boshqa belgi |
a\|b |
Chap yoki o‘ng variant | cat\|dog |
cat yoki dog |
() |
Guruhlash va natijani tutish | (ab)+ |
ab, abab |
Go regexida \d, \w va \b kabi Perl sinflari ASCII qoidalariga asoslanadi. O‘zbek harflari va boshqa Unicode belgilar uchun \p{L} — harf, \p{N} — raqam kabi Unicode sinflaridan foydalaning.
Maxsus belgining o‘zini qidirish uchun uni \ bilan escape qilish kerak. Masalan, . istalgan belgini anglatadi, \. esa oddiy nuqtaga mos keladi.
Go’da regex kompilyatsiya qilish
Go standart kutubxonasidagi regexp paketi regex bilan ishlaydi. Avval matnli pattern *regexp.Regexp obyektiga kompilyatsiya qilinadi.
Natija:
Backtick bilan yozilgan raw string ichida \d uchun qo‘shimcha escape kerak emas. Oddiy qo‘shtirnoqli Go satrida ayni pattern "\\d{4}-\\d{2}-\\d{2}" ko‘rinishida yozilardi.
regexp.MustCompile() pattern xato bo‘lsa panic qiladi. Kod ichida oldindan ma’lum, o‘zgarmas pattern uchun bu qulay: xato dastur ishlab chiqilayotgan paytda aniqlanadi.
Qidirish va to‘liq validatsiya farqi
MatchString() satrning istalgan qismi mos kelsa true qaytaradi. Telefon raqami butun satrni egallashi kerak bo‘lsa, ^ va $ chegaralari yoziladi:
Natija:
\+ oddiy + belgisini bildiradi. [0-9]{9} mamlakat kodidan keyin aynan to‘qqiz raqam talab qiladi. Chegaralarsiz pattern ikkinchi matn ichidan ham raqamni topib, true qaytarardi.
Regex faqat formatni tekshiradi. Telefon raqami haqiqatan ajratilganini, faol ekanini yoki operator diapazoniga kirishini alohida biznes qoidalari tekshiradi.
Barcha mosliklarni topish
FindAllString() matndagi barcha mos qismlarni qaytaradi:
Natija:
Ikkinchi argument maksimal natijalar sonidir. -1 barcha mosliklarni, 2 esa dastlabki ikkitasini qaytaradi. Moslik topilmasa, metod nil slice qaytaradi.
Bu misol sonlarni satr sifatida ajratadi. Ular bilan arifmetik amal bajarish uchun har bir qiymatni strconv.Atoi() orqali intga o‘tkazish va xatoni tekshirish kerak.
Guruhlar orqali qismlarni ajratish
Qavs ichidagi pattern tutuvchi guruh (capturing group) yaratadi. FindStringSubmatch() to‘liq moslik va guruhlarni qaytaradi:
Natija:
parts[0] to‘liq moslik, keyingi elementlar qavs ichidagi guruhlardir. parts == nil tekshirilmasa, moslik yo‘q paytda indeksga murojaat panic qiladi.
Faqat guruhlash kerak, ammo natijani tutish kerak bo‘lmasa, (?:...) ishlatiladi. Nomlangan guruhlar (?P<name>...) ko‘rinishida yoziladi va SubexpNames() orqali nomlarini olish mumkin.
Matnni almashtirish
ReplaceAllString() barcha mosliklarni almashtiradi. Masalan, ketma-ket bo‘sh joylarni bitta bo‘sh joyga keltiramiz:
Natija:
\s+ bir yoki bir nechta whitespace belgisiga mos keladi. Almashtirishdan keyingi bosh va oxirgi bo‘sh joyni strings.TrimSpace() olib tashlaydi. Faqat bo‘sh joylarni normallashtirish uchun strings.Fields() yanada sodda bo‘lishi mumkin; regex murakkabroq almashtirish qoidalarida foydali.
Almashtirish matnidagi $1 yoki ${name} tutuvchi guruh qiymatini bildiradi. Dollar belgisini oddiy matn sifatida qo‘shish kerak bo‘lsa, ReplaceAllString()ning replacement sintaksisini hisobga oling yoki ReplaceAllStringFunc() ishlating.
Tashqaridan kelgan pattern
Pattern konfiguratsiya yoki foydalanuvchidan kelsa, MustCompile() serverni panic bilan to‘xtatishi mumkin. Bunday holatda regexp.Compile() xatosini boshqaring:
Natijadagi xato matni Go versiyasiga qarab biroz farq qilishi mumkin:
Compile() muvaffaqiyatli bo‘lsa, re ishlatishga tayyor bo‘ladi. Web API’da to‘liq ichki parser xatosini mijozga qaytarish o‘rniga tushunarli validatsiya xabari berish ma’qul.
Email va URL validatsiyasi
Quyidagi soddalashtirilgan pattern odatiy email ko‘rinishini tekshiradi:
(?i) katta-kichik harfni farqlamaslikni yoqadi. Bu pattern ko‘plab amaliy manzillarni qabul qiladi, ammo email standartining barcha holatlarini ifodalamaydi va domen mavjudligini tekshirmaydi. Account ro‘yxatdan o‘tkazishda yakuniy tekshiruv — tasdiqlash xatini yuborish.
URL’ni murakkab regex bilan to‘liq validatsiya qilish o‘rniga net/url.ParseRequestURI() yoki vazifaga mos parserdan foydalaning. Parser scheme, host, escaping va query kabi qismlarni tuzilmali ko‘rinishda beradi. Regex faqat loyiha talab qilgan tor formatni tekshirish uchun qo‘shimcha qatlam bo‘lishi mumkin.
Go regex dvigatelining xususiyatlari
Go regexp paketi RE2 sintaksisiga asoslanadi va matching vaqtini kirish hajmiga nisbatan chiziqli saqlashga mo‘ljallangan. Ko‘plab backtracking dvigatellarida uchraydigan catastrophic backtracking xavfi shu dizayn bilan cheklanadi.
Buning evaziga ayrim imkoniyatlar qo‘llanmaydi:
- backreference:
\1,\k<name>; - oldinga yoki orqaga qarash (lookahead va lookbehind):
(?=...),(?!...),(?<=...); - shartli va rekursiv patternlar.
Masalan, takrorlangan aynan bir xil so‘zni backreference bilan qidirib bo‘lmaydi. Kerakli qismlarni guruh bilan ajratib, Go kodida solishtirish kerak.
*regexp.Regexp qiymati kompilyatsiyadan keyin bir nechta goroutine tomonidan xavfsiz ishlatilishi mumkin. Doimiy patternni har request ichida qayta kompilyatsiya qilmang. Uni paket darajasida bir marta tayyorlash CPU va allocation sarfini kamaytiradi.
Unicode va bayt indekslari
Go regex matnni UTF-8 kodlangan Unicode code pointlar sifatida ko‘radi. . odatda bitta rune’ga mos keladi. Ammo indeks qaytaradigan metodlar, masalan FindStringIndex(), natijani rune emas, bayt offsetlari sifatida beradi.
O‘zbek va boshqa Unicode harflarini tekshirish uchun:
Natija:
\p{L} istalgan Unicode harfiga mos keladi. [’'] tipografik va oddiy apostrofni qabul qiladi. Raqam guruhga kirmagani uchun go123 mos kelmaydi. Real ism validatsiyasi bundan murakkab: tire, bo‘sh joy va turli yozuv tizimlariga oid biznes qoidalarini alohida belgilang.
Keng tarqalgan xatolar
- Validatsiya patternida
^va$ni unutish. Natijada satrning kichik mos qismi butun qiymatni haqiqiy qilib ko‘rsatadi. - Raw string va oddiy Go string escapingini aralashtirish. Regexlar uchun backtick ko‘pincha o‘qilishi oson.
MustCompile()ni foydalanuvchi patterni bilan chaqirish. Noto‘g‘ri pattern serverni panic bilan to‘xtatadi.- Har requestda bir xil regexni qayta kompilyatsiya qilish. Tayyor
*regexp.Regexpni qayta ishlating. FindStringSubmatch()natijasininilga tekshirmasdan indekslash.\wbarcha Unicode harflarini qamrab oladi deb o‘ylash. Unicode uchun\p{L}kabi sinflarni ishlating.- Regex sintaksis mosligini ma’lumotning haqiqiyligi bilan tenglashtirish. Sana, URL, email va telefon uchun semantik tekshiruv ham kerak.
- Oddiy vazifani murakkab regex bilan hal qilish. Maxsus parser yoki
stringsfunksiyasi kodni aniqroq qiladi.
Interviewda nimalarga e’tibor beriladi?
MatchString()qisman moslikni ham qabul qilishi va validatsiyada chegaralar zarurligi.Compile()vaMustCompile()ning farqi.- Go regexining RE2 asosida chiziqli vaqt kafolatiga ega bo‘lishi.
- Backreference va lookaround qo‘llanmasligi.
FindString,FindAllString,FindStringSubmatchvaReplaceAllStringvazifalari.- Unicode sinflari va indekslarning bayt offseti sifatida qaytishi.
- Tayyor
*regexp.Regexpni concurrent va takroran ishlatish mumkinligi.
Xulosa
Regex matndagi shakllarni topish, validatsiya qilish va almashtirish uchun ishlatiladi. Go’ning regexp paketi RE2 sintaksisiga asoslanadi va kirish hajmiga nisbatan chiziqli ishlashga mo‘ljallangan. Doimiy patternni bir marta kompilyatsiya qiling, tashqi pattern xatosini boshqaring va regex formatni tekshirishi bilan ma’lumotning haqiqiyligini isbotlashini aralashtirmang.