JavaRush /Java blogi /Random-UZ /RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa q...
Artur
Daraja
Tallinn

RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam. 2-qism

Guruhda nashr etilgan
RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam. 1-qism Original bu yerda Oxirgi qismda biz eng oddiy oddiy iboralarni o'zlashtirdik va allaqachon nimanidir o'rgandik. Ushbu qismda biz biroz murakkabroq dizaynlarni o'rganamiz, lekin menga ishoning, bu ko'rinadigan darajada qiyin bo'lmaydi. RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam.  2-1-qismShunday ekan, davom etaylik!

8-qadam: Yulduz *va ortiqcha belgisi+

RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam.  2-2 qismHozircha biz ko'proq yoki kamroq faqat ma'lum uzunlikdagi satrlarni moslashtira oldik. Ammo so'nggi muammolarda biz hozirgacha ko'rgan belgilar bilan nima qilishimiz mumkin bo'lgan chegaraga yaqinlashdik. Masalan, biz 3 ta belgidan iborat Java identifikatorlari bilan cheklanib qolmay, istalgan uzunlikdagi identifikatorlarga ega bo'lishimiz mumkin, deb faraz qilaylik. Oldingi misolda ishlagan yechim quyidagi misolda ishlamaydi:
naqsh: [a-zA-Z_$]\w\w 
string:   __e $12 3 3.2 fo Bar r a23 mm ab x
mos keladi: ^^^ ^^^ ^^^ ^^^  
( Misol ) EslatmaAgar identifikator to'g'ri bo'lsa, lekin 3 belgidan uzun bo'lsa, faqat dastlabki uchta belgi mos keladi. Agar identifikator to'g'ri bo'lsa, lekin 3 tadan kam belgidan iborat bo'lsa, regex uni umuman topa olmaydi! Muammo shundaki, qavs ichidagi iboralar []xuddi bitta belgiga mos keladi, masalan, belgilar sinflari \w. Bu shuni anglatadiki, yuqoridagi oddiy iboradagi har qanday moslik to'liq uch belgidan iborat bo'lishi kerak. Demak, bu biz kutgandek ishlamayapti. *Maxsus belgilar va bu erda yordam berishi mumkin +. Bular har qanday iboraning oʻng tomoniga qoʻshilishi mumkin boʻlgan modifikatorlar boʻlib, bu iboraga bir necha marta mos keladi. Kleene yulduzi (yoki "yulduzcha") *oldingi tokenga har qanday marta, jumladan, nol marta mos kelishi kerakligini ko'rsatadi. Plyus belgisi +bir yoki bir necha marta qidirishingiz kerakligini ko'rsatadi. Shunday qilib, oldingi ibora +majburiy (kamida bir marta), oldingi ibora esa *ixtiyoriy, lekin paydo bo'lganda, u bir necha marta paydo bo'lishi mumkin. Endi, ushbu bilim bilan biz yuqoridagi muntazam ifodani tuzatishimiz mumkin:
naqsh: [a-zA-Z_$]\w* 
string:   __e $123 3.2 Barr a23mm ab x 
mos keladi: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^ 
( Misol ) Endi biz istalgan uzunlikdagi haqiqiy identifikatorlarni moslashtiramiz! Bingo! Agar biz +o'rniga ? ni ishlatsak nima bo'lar edi *?
naqsh: [a-zA-Z_$]\w+ 
string:   __e Barr a23mm ab x uchun $123 3.2
mos keladi: ^^^^^^^^^^^^^^^^^^^^^^^^ 
( Misol ) Biz oxirgi o'yinni o'tkazib yubordik, х. Buning sababi shundaki, u +kamida bitta belgini moslashtirishni talab qiladi, lekin []oldingi qavs ichidagi ibora \w+allaqachon belgini "egan" ligi sababli x, boshqa belgilar mavjud emas, shuning uchun mos kelmaydi. Qachon foydalanishimiz mumkin +? Biz kamida bitta moslikni topishimiz kerak bo'lganda, lekin berilgan ifoda necha marta mos kelishi muhim emas. Misol uchun, agar biz kasrli nuqtani o'z ichiga olgan har qanday raqamni topmoqchi bo'lsak:
naqsh: \d*\.\d+ 
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 
mos keladi: ^^^^^ ^^^^^^^^^^^^^^^^^^^^  
( Misol ) Eslatmao'nli kasrning chap tomonidagi raqamlarni ixtiyoriy qilish orqali biz 0,011 va .2 ni ham topa oldik. Buni amalga oshirish uchun biz o'nli kasrning \.o'ng tomonidagi kamida bitta raqamni va o'nli kasrni bilan moslashtirishimiz kerak edi \d+. Yuqoridagi oddiy ibora kabi raqamga mos kelmaydi 3., chunki mos kelish uchun kasrning oʻng tomonida kamida bitta raqam kerak.

Odatdagidek, bir nechta oddiy muammolarni hal qilaylik:

Quyidagi parchadan barcha inglizcha so'zlarni toping.
naqsh:
satr: 3 plus 3 olti, lekin 4 plus uch 7
mos keladi:    ^^^^ ^^ ^^^ ^^^ ^^^^^^^^^^^^ 
( Yechim ) Quyidagi roʻyxatdagi barcha fayl oʻlchami belgilarini toping. Fayl oʻlchamlari raqamdan (oʻnli kasrli yoki kasrsiz) va undan keyin KB, yoki MBdan iborat boʻladi : GBTB
naqsh:
string:   11TB 13 14.4MB 22HB 9.9GB TB 0KB 
mos keladi: ^^^^ ^^^^^^^^^^^^^^  
( Yechim )

9-qadam: "ixtiyoriy" savol belgisi?

RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam.  2-3 qismOxirgi muammoni hal qilish uchun regexni allaqachon yozganmisiz? Ishladimi? Endi uni bu erda qo'llashga harakat qiling:
naqsh:
qator: 1..3KB 5...GB ..6TB
mos keladi:  
Shubhasiz, bu belgilarning hech biri to'g'ri fayl hajmi emas, shuning uchun yaxshi muntazam ifoda ularning hech biriga mos kelmasligi kerak. Oxirgi muammoni hal qilish uchun men yozgan yechim ularning barchasiga mos keladi, hech bo'lmaganda qisman:
naqsh: \d+\.*\d*[KMGT]B 
qator:   1..3KB  5...GB .. 6TB 
mos keladi: ^^^^^^ ^^^^^^ ^^^ 
( Misol ) Xo'sh, muammo nimada? Aslida, agar mavjud bo'lsa, biz faqat bitta kasr nuqtasini topishimiz kerak. Lekin *u har qanday miqdordagi o'yinlarga, shu jumladan nolga ham ruxsat beradi. Faqat nol marta yoki bir marta mos keladigan usul bormi? Lekin bir martadan ortiq emasmi? Albatta bor. "ixtiyoriy" ?nolga yoki oldingi belgilardan biriga mos keladigan modifikator, lekin ortiq emas:
naqsh: \d+\.?\d*[KMGT]B 
qator: 1.. 3KB 5...GB .. 6TB 
mos keladi:     ^^^ ^^^ 
( Misol ) Biz bu erda yechimga yaqinroqmiz, lekin bu bizga kerak bo'lgan narsa emas. Buni qanday tuzatish kerakligini birozdan keyin ko'rib chiqamiz.

Ayni paytda, keling, ushbu muammoni hal qilaylik:

Ba'zi dasturlash tillarida (masalan, Java) ba'zi bir butun va suzuvchi nuqtali (nuqta) raqamlardan keyin ularni oddiy int/double emas, balki uzun/suzuvchi (mos ravishda) sifatida ko'rish kerakligini ko'rsatish uchun l/ Lva f/ qo'shilishi mumkin. FQuyidagi qatordagi barcha haqiqiy "uzun" raqamlarni toping:
naqsh:
tor:   13L uzun 2l 19 L lL 0 
ta mos: ^^^ ^^ ^^ ^ 
( Yechim )

10-qadam: "yoki" belgisi|

RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam.  2-4 qism8-bosqichda biz suzuvchi nuqtali raqamlarning har xil turlarini topishda biroz qiyinchiliklarga duch keldik:
naqsh: \d*\.\d+ 
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 
mos keladi: ^^^^^ ^^^^^^^^^^^^^^^^^^^^  
Yuqoridagi naqsh o'nli kasrli raqamlarga va kasrning o'ng tomonidagi kamida bitta raqamga mos keladi. Ammo shunga o'xshash satrlarni moslashtirmoqchi bo'lsak-chi 0.? (O'nli kasrning o'ng tomonida raqamlar yo'q.) Biz shunday oddiy ifoda yozishimiz mumkin:
naqsh: \d*\.\d* 
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. . 
o'yinlar: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^ ^ 
( Misol ) Bu mos keladi , lekin yuqorida ko'rib turganingizdek, 0.bitta nuqtaga ham mos keladi . .Aslida biz mos kelmoqchi bo'lgan narsa ikki xil string sinfidir:
  1. kasrning o'ng tomonida kamida bitta raqam bo'lgan raqamlar
  2. kasrning chap tomonida kamida bitta raqam bo'lgan raqamlar
Quyidagi 2 ta muntazam iborani bir-biridan mustaqil yozamiz:
naqsh: \d*\.\d+ 
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. .
mos keladi: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  
naqsh: \d+\.\d* 
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. .
mos keladi: ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ 
Biz ushbu holatlarning hech birida 42, 5yoki pastki qatorlar dvigatel tomonidan topilmasligini ko'ramiz. Kerakli natijaga erishish uchun ushbu muntazam iboralarni birlashtirganimiz bizga zarar keltirmaydi. Bunga qanday erishishimiz mumkin? "Yoki" belgisi muntazam ifodada bir vaqtning o'zida bir nechta mumkin bo'lgan mos keluvchi ketma-ketlikni ko'rsatishga imkon beradi. Xuddi "yoki" belgisi muqobil bitta belgilarni ko'rsatishga imkon berganidek, muqobil ko'p belgili ifodalarni ham belgilashimiz mumkin. Misol uchun, agar biz "it" yoki "mushuk" ni topmoqchi bo'lsak, biz shunday yozishimiz mumkin: 6.|[]|
naqsh: \w\w\w 
string:   Shubhasiz , it mushukdan ko'ra yaxshiroq uy hayvonidir .
mos keladi: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
( Misol ) ... lekin bu "so'z" sinfining barcha uchli belgilar ketma-ketligiga mos keladi. Ammo "it" va "mushuk" ning umumiy harflari ham yo'q, shuning uchun kvadrat qavslar bu erda bizga yordam bermaydi. Mana, biz ishlatishimiz mumkin bo'lgan eng oddiy oddiy ibora ikkala va faqat ushbu ikkita so'zga mos keladi:
naqsh: it|mushuk 
ipi: Shubhasiz, it mushukdan ko'ra yaxshiroq uy hayvonidir .
mos keladi:               ^^^ ^^^ 
( Misol ) Muntazam ifoda mexanizmi avval butun ketma-ketlikni belgining chap tomoniga moslashtirishga harakat qiladi |, lekin agar u muvaffaqiyatsiz bo'lsa, keyin belgining o'ng tomonidagi ketma-ketlikni moslashtirishga harakat qiladi |. Bir nechta belgilar |ikkitadan ortiq muqobil ketma-ketliklarga mos kelishi uchun zanjirlangan bo'lishi mumkin:
naqsh: it|mushuk|uy hayvonlari qatori 
: Shubhasiz, it mushukdan yaxshiroq uy hayvonidir .
mos keladi:               ^^^ ^^^ ^^^ 
( Misol )

Keling, ushbu bosqichni yaxshiroq tushunish uchun yana bir nechta muammolarni hal qilaylik:

|Quyidagi kabi natijani olish uchun yuqoridagi o'nlik muntazam ifodani tuzatish uchun belgidan foydalaning :
naqsh:
satr:   0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0 ..
mos keladi: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
( Yechim ) Oldingi bosqich oxiridagi masalada muhokama qilinganidek, butun son va suzuvchi nuqta (nuqta) raqamlariga mos keladigan yagona muntazam ifoda yaratish uchun belgi |, belgilar sinflari, “ixtiyoriy” va hokazolardan foydalaning (bu muammo biroz ?murakkabroq, ha;))
naqsh:
string:   42L 12 x 3.4f 6l 3.3 0F LF .2F 0. 
mos keladi: ^^^ ^^^^^^^^^^^^^^^^^^^^^^  
( Yechim ) Muntazam iboralarni o'zlashtirish uchun 20 ta qisqa qadam. 3-qism RegEx: Oddiy iboralarni o'zlashtirish uchun 20 ta qisqa qadam. 4-qism
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION