Ushbu maqolada biz regexplar bilan ishlaydigan turli usullarni chuqur ko’rib chiqamiz.
str.match(regexp)
str.match(regexp) usuli str satrida regexp uchun mosliklarni topadi.
Uning 3 ta rejimi bor:
-
Agar
regexpdagbayrog’i bo’lmasa, u birinchi moslikni tutuvchi guruhlar vaindex(moslik pozitsiyasi),input(kirish satri,strga teng) xususiyatlari bilan massiv sifatida qaytaradi:let str = "Men JavaScriptni yaxshi ko'raman"; let result = str.match(/Java(Script)/); alert( result[0] ); // JavaScript (to'liq moslik) alert( result[1] ); // Script (birinchi tutuvchi guruh) alert( result.length ); // 2 // Qo'shimcha ma'lumot: alert( result.index ); // 4 (moslik pozitsiyasi) alert( result.input ); // Men JavaScriptni yaxshi ko'raman (manba satr) -
Agar
regexpdagbayrog’i bo’lsa, u barcha mosliklarni tutuvchi guruhlar va boshqa tafsilotlarsiz satrlar sifatida massiv qaytaradi.let str = "Men JavaScriptni yaxshi ko'raman"; let result = str.match(/Java(Script)/g); alert( result[0] ); // JavaScript alert( result.length ); // 1 -
Agar mosliklar bo’lmasa,
gbayrog’i bor yoki yo’qligidan qat’i nazar,nullqaytariladi.Bu muhim nüans. Agar mosliklar bo’lmasa, biz bo’sh massiv emas, balki
nullolamiz. Buni unutish va xato qilish oson, masalan:let str = "Men JavaScriptni yaxshi ko'raman"; let result = str.match(/HTML/); alert(result); // null alert(result.length); // Xato: Cannot read property 'length' of nullAgar natija massiv bo’lishini istasak, quyidagicha yozishimiz mumkin:
let result = str.match(regexp) || [];
str.matchAll(regexp)
str.matchAll(regexp) usuli str.match ning “yangilangan, yaxshilangan” variantidir.
U asosan barcha guruhlar bilan barcha mosliklarni qidirish uchun ishlatiladi.
match dan 3 ta farqi bor:
- U massiv o’rniga mosliklar bilan takrorlanadigan obyekt qaytaradi. Biz undan
Array.fromyordamida oddiy massiv yasashimiz mumkin. - Har bir moslik tutuvchi guruhlar bilan massiv sifatida qaytariladi (
gbayrog’isizstr.matchbilan bir xil format). - Agar natijalar bo’lmasa, u
nullo’rniga bo’sh takrorlanadigan obyekt qaytaradi.
Foydalanish misoli:
let str = '<h1>Salom, dunyo!</h1>';
let regexp = /<(.*?)>/g;
let matchAll = str.matchAll(regexp);
alert(matchAll); // [object RegExp String Iterator], massiv emas, lekin takrorlanadigan
matchAll = Array.from(matchAll); // endi massiv
let firstMatch = matchAll[0];
alert( firstMatch[0] ); // <h1>
alert( firstMatch[1] ); // h1
alert( firstMatch.index ); // 0
alert( firstMatch.input ); // <h1>Salom, dunyo!</h1>
Agar biz matchAll mosliklarini aylanib chiqish uchun for..of dan foydalansak, endi Array.from kerak emas.
str.split(regexp|substr, limit)
Satrni regexp (yoki pastki satr) ni ajratuvchi sifatida ishlatib bo’ladi.
Biz split ni satrlar bilan ishlatishimiz mumkin, masalan:
alert('12-34-56'.split('-')) // ['12', '34', '56'] massivi
Ammo biz muntazam ifoda bilan ham xuddi shunday bo’lishimiz mumkin:
alert('12, 34, 56'.split(/,\s*/)) // ['12', '34', '56'] massivi
str.search(regexp)
str.search(regexp) usuli birinchi moslikning pozitsiyasini yoki topilmasa -1 ni qaytaradi:
let str = "Siyoh tomchisi millionlarni o'ylantirishi mumkin";
alert( str.search( /siyoh/i ) ); // 0 (birinchi moslik pozitsiyasi)
Muhim cheklov: search faqat birinchi moslikni topadi.
Agar bizga keyingi mosliklar pozitsiyalari kerak bo’lsa, str.matchAll(regexp) bilan barchasini topish kabi boshqa vositalardan foydalanishimiz kerak.
str.replace(str|regexp, str|func)
Bu qidirish va almashtirish uchun umumiy usul, eng foydalilaridan biri. Qidirish va almashtirish uchun universal vosita.
Biz uni regexplarsiz, pastki satrni qidirish va almashtirish uchun ishlatishimiz mumkin:
// defisni ikki nuqta bilan almashtirish
alert('12-34-56'.replace("-", ":")) // 12:34-56
Biroq, tuzoq bor.
replace ning birinchi argumenti satr bo’lsa, u faqat birinchi moslikni almashtiradi.
Buni yuqoridagi misolda ko’rishingiz mumkin: faqat birinchi "-" ":" bilan almashtiriladi.
Barcha defislarni topish uchun biz "-" satrini emas, balki majburiy g bayrog’i bilan /-/g regexp dan foydalanishimiz kerak:
// barcha defislarni ikki nuqta bilan almashtirish
alert( '12-34-56'.replace( /-/g, ":" ) ) // 12:34:56
Ikkinchi argument almashtirish satridir. Biz unda maxsus belgilardan foydalanishimiz mumkin:
| Belgilar | Almashtirish satridagi harakat |
|---|---|
$& |
butun moslikni qo’yadi |
$` |
moslikdan oldingi satr qismini qo’yadi |
$' |
moslikdan keyingi satr qismini qo’yadi |
$n |
agar n 1-2 xonali raqam bo’lsa, n-chi tutuvchi guruh tarkibini qo’yadi, tafsilotlar uchun Ushlash guruhlari ga qarang |
$<name> |
berilgan name ga ega qavslar tarkibini qo’yadi, tafsilotlar uchun Ushlash guruhlari ga qarang |
$$ |
$ belgisini qo’yadi |
Masalan:
let str = "John Smith";
// ism va familiyani almashtirish
alert(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John
“Aqlli” almashtirishlar talab qiladigan holatlar uchun ikkinchi argument funksiya bo’lishi mumkin.
U har bir moslik uchun chaqiriladi va qaytarilgan qiymat almashtirish sifatida qo’yiladi.
Funksiya func(match, p1, p2, ..., pn, offset, input, groups) argumentlari bilan chaqiriladi:
match– moslik,p1, p2, ..., pn– tutuvchi guruhlar tarkibi (agar mavjud bo’lsa),offset– moslik pozitsiyasi,input– manba satr,groups– nomlangan guruhlar bilan obyekt.
Agar regexpda qavslar bo’lmasa, faqat 3 ta argument bor: func(str, offset, input).
Masalan, barcha mosliklarni katta harflarga o’tkazaylik:
let str = "html va css";
let result = str.replace(/html|css/gi, str => str.toUpperCase());
alert(result); // HTML va CSS
Har bir moslikni satrdagi pozitsiyasi bilan almashtirish:
alert("Ho-Ho-ho".replace(/ho/gi, (match, offset) => offset)); // 0-3-6
Quyidagi misolda ikkita qavs bor, shuning uchun almashtirish funksiyasi 5 ta argument bilan chaqiriladi: birinchisi to’liq moslik, keyin 2 ta qavs, va undan keyin (misolda ishlatilmagan) moslik pozitsiyasi va manba satr:
let str = "John Smith";
let result = str.replace(/(\w+) (\w+)/, (match, name, surname) => `${surname}, ${name}`);
alert(result); // Smith, John
Agar ko’p guruhlar bo’lsa, ularga kirish uchun qolgan parametrlardan foydalanish qulay:
let str = "John Smith";
let result = str.replace(/(\w+) (\w+)/, (...match) => `${match[2]}, ${match[1]}`);
alert(result); // Smith, John
Yoki agar biz nomlangan guruhlardan foydalansak, groups obyekti ular bilan har doim oxirgi bo’ladi, shuning uchun uni quyidagicha olishimiz mumkin:
let str = "John Smith";
let result = str.replace(/(?<name>\w+) (?<surname>\w+)/, (...match) => {
let groups = match.pop();
return `${groups.surname}, ${groups.name}`;
});
alert(result); // Smith, John
Funksiyadan foydalanish bizga yakuniy almashtirish kuchini beradi, chunki u moslik haqida barcha ma’lumotlarni oladi, tashqi o’zgaruvchilarga kirish imkoniga ega va hamma narsani qila oladi.
str.replaceAll(str|regexp, str|func)
Bu usul asosan str.replace bilan bir xil, ikkita katta farq bilan:
- Agar birinchi argument satr bo’lsa, u satrning barcha takrorlanishlarini almashtiradi,
replaceesa faqat birinchi takrorlanishni almashtiradi. - Agar birinchi argument
gbayrog’isiz muntazam ifoda bo’lsa, xatolik bo’ladi.gbayrog’i bilan ureplacekabi ishlaydi.
replaceAll ning asosiy foydalanish holati satrning barcha takrorlanishlarini almashtirish.
Masalan:
// barcha defislarni ikki nuqta bilan almashtirish
alert('12-34-56'.replaceAll("-", ":")) // 12:34:56
regexp.exec(str)
regexp.exec(str) usuli str satrida regexp uchun moslik qaytaradi. Oldingi usullardan farqli o’laroq, u satrda emas, balki regexpda chaqiriladi.
U regexpda g bayrog’i bor-yo’qligiga qarab turlicha harakat qiladi.
Agar g bo’lmasa, regexp.exec(str) birinchi moslikni aniq str.match(regexp) kabi qaytaradi. Bu xatti-harakat yangi hech narsa keltirmaydi.
Ammo agar g bayrog’i bo’lsa:
regexp.exec(str)ga chaqiruv birinchi moslikni qaytaradi va undan keyin pozitsiyaniregexp.lastIndexxususiyatida saqlaydi.- Keyingi bunday chaqiruv qidiruvni
regexp.lastIndexpozitsiyasidan boshlaydi, keyingi moslikni qaytaradi va undan keyingi pozitsiyaniregexp.lastIndexda saqlaydi. - …Va hokazo.
- Agar mosliklar bo’lmasa,
regexp.execnullqaytaradi varegexp.lastIndexni0ga qayta o’rnatadi.
Shunday qilib, takroriy chaqiruvlar joriy qidiruv pozitsiyasini kuzatib borish uchun regexp.lastIndex xususiyatidan foydalanib, barcha mosliklarni birin-ketin qaytaradi.
O’tmishda, str.matchAll usuli JavaScript ga qo’shilgunga qadar, regexp.exec chaqiruvlari guruhlar bilan barcha mosliklarni olish uchun tsiklda ishlatilgan:
let str = 'JavaScript haqida batafsil https://javascript.info da';
let regexp = /javascript/ig;
let result;
while (result = regexp.exec(str)) {
alert( `${result[0]} ni ${result.index} pozitsiyasida topdi` );
// JavaScript ni 0 pozitsiyasida topdi, keyin
// javascript ni 32 pozitsiyasida topdi
}
Bu hozir ham ishlaydi, garchi yangi brauzerlar uchun str.matchAll odatda qulayroq.
Biz lastIndex ni qo’lda o’rnatish orqali berilgan pozitsiyadan qidirish uchun regexp.exec dan foydalanishimiz mumkin.
Masalan:
let str = 'Salom, dunyo!';
let regexp = /\w+/g; // "g" bayrog'isiz lastIndex xususiyati e'tiborga olinmaydi
regexp.lastIndex = 5; // 5-pozitsiyadan qidirish (verguldan)
alert( regexp.exec(str) ); // dunyo
Agar regexpda y bayrog’i bo’lsa, qidiruv aniq regexp.lastIndex pozitsiyasida amalga oshiriladi, undan uzoqroq emas.
Yuqoridagi misolda g bayrog’ini y bilan almashtiraylik. Mosliklar bo’lmaydi, chunki 5-pozitsiyada so’z yo’q:
let str = 'Salom, dunyo!';
let regexp = /\w+/y;
regexp.lastIndex = 5; // aniq 5-pozitsiyada qidirish
alert( regexp.exec(str) ); // null
Bu biz satrdan aniq pozitsiyada regexp bilan biror narsani “o’qishimiz” kerak bo’lgan holatlar uchun qulay, uzoqroq joyda emas.
regexp.test(str)
regexp.test(str) usuli moslik qidiradi va u mavjudligiga qarab true/false qaytaradi.
Masalan:
let str = "Men JavaScriptni yaxshi ko'raman";
// bu ikki test bir xil
alert( /yaxshi/i.test(str) ); // true
alert( str.search(/yaxshi/i) != -1 ); // true
Salbiy javob bilan misol:
let str = "Bla-bla-bla";
alert( /yaxshi/i.test(str) ); // false
alert( str.search(/yaxshi/i) != -1 ); // false
Agar regexpda g bayrog’i bo’lsa, regexp.test regexp.lastIndex xususiyatidan qaraydi va bu xususiyatni yangilaydi, xuddi regexp.exec kabi.
Shuning uchun biz uni berilgan pozitsiyadan qidirish uchun ishlatishimiz mumkin:
let regexp = /yaxshi/gi;
let str = "Men JavaScriptni yaxshi ko'raman";
// 10-pozitsiyadan qidiruvni boshlash:
regexp.lastIndex = 10;
alert( regexp.test(str) ); // false (moslik yo'q)
Agar biz bir xil global regexpni turli kirishlarga qo’llasak, bu noto’g’ri natijaga olib kelishi mumkin, chunki regexp.test chaqiruvi regexp.lastIndex xususiyatini oldinga siljitadi, shuning uchun boshqa satrdagi qidiruv noldan boshqa pozitsiyadan boshlana oladi.
Masalan, bu yerda biz bir xil matnda regexp.test ni ikki marta chaqiramiz va ikkinchi marta muvaffaqiyatsiz bo’ladi:
let regexp = /javascript/g; // (regexp hozirgina yaratildi: regexp.lastIndex=0)
alert( regexp.test("javascript") ); // true (regexp.lastIndex=10 endi)
alert( regexp.test("javascript") ); // false
Bu aniq regexp.lastIndex ikkinchi testda noldan farq qilgani uchun.
Buni hal qilish uchun har bir qidiruvdan oldin regexp.lastIndex = 0 o’rnatishimiz mumkin. Yoki regexp usullarini chaqirish o’rniga lastIndex dan foydalanmaydigan str.match/search/... satr usullaridan foydalaning.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepen…)