JavaRush /Java blogi /Random-UZ /Java tilidagi oddiy iboralar (RegEx)

Java tilidagi oddiy iboralar (RegEx)

Guruhda nashr etilgan
Muntazam iboralar - bu dasturchilar, hatto tajribalilar ham, ko'pincha keyinroq qoldiradigan mavzu. Biroq, ko'pchilik Java dasturchilari ertami-kechmi matnni qayta ishlash bilan shug'ullanishlari kerak. Ko'pincha - matn va tahrirdagi qidiruv operatsiyalari bilan. Muntazam ifodalarsiz matnni qayta ishlash bilan bog'liq samarali va ixcham dastur kodini tasavvur qilib bo'lmaydi. Shuning uchun uni kechiktirishni to'xtating, keling, hozir "muntazam" bilan shug'ullanamiz. Bu unchalik qiyin ish emas.

RegEx muntazam ifodasi nima?

Darhaqiqat, muntazam ifoda (Javada RegEx) matndagi satrni qidirish uchun namunadir. Java-da bu naqshning dastlabki ko'rinishi har doim string, ya'ni String sinfining ob'ekti bo'ladi. Biroq, har qanday satrni muntazam ifodaga kompilyatsiya qilish mumkin emas, faqat oddiy iborani yozish qoidalariga rioya qiladiganlar - til spetsifikatsiyasida belgilangan sintaksis. Muntazam iborani yozish uchun alifbo va raqamli belgilar, shuningdek, metabelgilar - muntazam iboralar sintaksisida alohida ma'noga ega bo'lgan belgilar ishlatiladi. Masalan:
String regex = "java"; // string template "java";
String regex = "\\d{3}"; // string template of three numeric characters;

Java-da muntazam ifodalarni yaratish

Java-da RegEx-ni yaratish uchun siz ikkita oddiy qadamni bajarishingiz kerak:
  1. uni muntazam ifoda sintaksisi yordamida satr sifatida yozing;
  2. bu qatorni muntazam ifodaga kompilyatsiya qilish;
Har qanday Java dasturida muntazam ifodalar bilan ishlash sinf ob'ektini yaratishdan boshlanadi Pattern. Buni amalga oshirish uchun siz sinfda mavjud bo'lgan ikkita statik usullardan birini chaqirishingiz kerak compile. Birinchi usul bitta argumentni oladi - oddiy iboraning satrli harfi, ikkinchisi - shablonni matn bilan taqqoslash rejimini yoqadigan yana bir parametr:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Mumkin bo'lgan parametr qiymatlari ro'yxatiflags sinfda aniqlangan Patternva biz uchun statik sinf o'zgaruvchilari sifatida mavjud. Masalan:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//searching for matches with the pattern will be done case-insensitively.
Asosan, sinf Patternmuntazam ifoda konstruktoridir. Kaput ostida usul kompilyatsiya qilingan ko'rinishni yaratish uchun compilesinfning shaxsiy konstruktorini chaqiradi . PatternShablon namunasini yaratishning ushbu usuli uni o'zgarmas ob'ekt sifatida yaratish maqsadi bilan amalga oshiriladi. Yaratishda muntazam ifodaning sintaksisi tekshiriladi. Agar qatorda xatolar bo'lsa, istisno hosil bo'ladi PatternSyntaxException.

Oddiy ifoda sintaksisi

<([{\^-=$!|]})?*+.>Muntazam ifoda sintaksisi alifbo belgilari bilan birlashtirilishi mumkin bo'lgan belgilardan foydalanishga asoslangan . Ularning roliga qarab, ularni bir necha guruhlarga bo'lish mumkin:
1. Chiziq chegaralari yoki matnga mos keladigan metabelgilar
Meta xarakter Maqsad
^ qatorning boshlanishi
$ qator oxiri
\b so'z chegarasi
\B so'z chegarasi emas
\A kiritish boshlanishi
\G oldingi o'yinning oxiri
\Z kiritish oxiri
\z kiritish oxiri
2. Belgilar sinflarini qidirish uchun meta-belgilar
Meta xarakter Maqsad
\d raqamli belgi
\D raqamli bo'lmagan belgi
\s kosmik belgi
\S bo'sh joy bo'lmagan belgi
\w alfanumerik belgi yoki pastki chiziq
\V alifbo, raqam yoki pastki chiziqdan boshqa har qanday belgi
. har qanday belgi
3. Matnni tahrirlash belgilarini qidirish uchun meta-belgilar
Meta xarakter Maqsad
\t yorliq belgisi
\n yangi qator belgisi
\r karetaning qaytish belgisi
\f yangi sahifaga o'ting
\u0085 keyingi qator belgisi
\u 2028 chiziq ajratuvchi belgi
\u 2029 paragraf ajratuvchi belgisi
4. Belgilarni guruhlash uchun meta-belgilar
Meta xarakter Maqsad
[a B C] yuqoridagilardan biri (a, b yoki c)
[^abc] sanab o'tilganlardan boshqa har qanday (a, b, c emas)
[a-zA-Z] diapazonni birlashtirish (lotincha a dan z gacha harflar katta-kichik harflarga sezgir emas)
[ad[mp]] belgilarni birlashtirish (a dan d va m dan p ga)
[az&&[def]] belgilarning kesishishi (d,e,f belgilari)
[az&&[^bc]] belgilarni ayirish (a, dz belgilar)
5. Belgilar sonini bildiruvchi metasimbollar - kvantifikatorlar. Miqdor ko'rsatkichi har doim belgi yoki belgilar guruhidan keyin keladi.
Meta xarakter Maqsad
? bitta yoki yo'q
* nol yoki undan ko'p marta
+ bir yoki bir necha marta
{n} n marta
{n,} n marta yoki undan ko'p
{n,m} n martadan kam emas va m martadan ko'p emas

Ochko'z miqdoriy belgilash rejimi

Miqdor ko'rsatkichlarining o'ziga xos xususiyati ularni turli xil rejimlarda ishlatish qobiliyatidir: ochko'z, o'ta ochko'z va dangasa. Qo'shimcha ochko'zlik rejimi+ miqdoriy belgidan keyin " " belgisini qo'shish orqali va dangasa rejimi " " belgisini qo'shish orqali yoqiladi ?. Masalan:
"A.+a" // greedy mode
"A.++a" // over-greedy mode
"A.+?a" // lazy mode
Ushbu shablonni misol sifatida ishlatib, keling, kvantifikatorlarning turli rejimlarda qanday ishlashini tushunishga harakat qilaylik. Odatiy bo'lib, miqdoriy belgi ochko'z rejimda ishlaydi. Bu shuni anglatadiki, u satrda mumkin bo'lgan eng uzun moslikni qidiradi. Ushbu kodni ishga tushirish natijasida:
public static void main(String[] args) {
    String text = "Egor Alla Alexander";
    Pattern pattern = Pattern.compile("A.+a");
    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        System.out.println(text.substring(matcher.start(), matcher.end()));
    }
}
biz quyidagi natijani olamiz: Alla Alexa Berilgan naqsh uchun qidiruv algoritmi " А.+а" quyidagi ketma-ketlikda amalga oshiriladi:
  1. Berilgan naqshda birinchi belgi ruscha harf belgisidir А. Matcheruni nol pozitsiyasidan boshlab matnning har bir belgisiga moslashtiradi. Matnimizda nol pozitsiyasida belgi mavjud Е, shuning uchun Matcheru naqsh bilan mos kelguncha matndagi belgilarni ketma-ket o'tadi. Bizning misolimizda bu 5-pozitsiyadagi belgi.

    Java tilidagi oddiy iboralar - 2
  2. Naqshning birinchi belgisi bilan moslik topilgach, Matcheru naqshning ikkinchi belgisi bilan mosligini tekshiradi. Bizning holatlarimizda, bu .har qanday belgini bildiruvchi "" belgisidir.

    Java tilidagi oddiy iboralar - 3

    Oltinchi pozitsiyada harf belgisi joylashgan л. Albatta, u "har qanday belgi" naqshiga mos keladi.

  3. Matchernaqshdan keyingi belgini tekshirishga o'tadi. Bizning shablonimizda u “ .+” miqdoriy ko'rsatkichi yordamida ko'rsatilgan. Naqshdagi “har qanday belgi”ning takrorlanish soni bir yoki bir necha marta bo‘lganligi sababli, Matcher“istalgan belgi” sharti bajarilgan taqdirda, u navbatdagi satrdan keyingi belgini oladi va naqshga muvofiqligini tekshiradi. bizning misolimizda - satr oxirigacha (matnning 7-sonli pozitsiyasidan - 18-son).

    Java tilidagi oddiy iboralar - 4

    Aslida, Matcheru butun chiziqni oxirigacha qamrab oladi - bu erda uning "ochko'zligi" o'zini namoyon qiladi.

  4. MatcherMatn oxiriga etib, naqshning “ ” qismini tekshirishni tugatgandan so'ng А.+, Matcher naqshning qolgan qismini - harf belgisini tekshirishni boshlaydi а. Oldinga yo'nalishdagi matn tugaganligi sababli, tekshirish oxirgi belgidan boshlab teskari yo'nalishda amalga oshiriladi:

    Java tilidagi oddiy iboralar - 5
  5. MatcherMatn oxiriga yetgan " " naqshidagi takrorlanishlar sonini "eslab qoladi .+", shuning uchun takrorlar sonini bittaga kamaytiradi va moslik topilmaguncha matn naqshini tekshiradi: Java tilidagi oddiy iboralar - 6

O'ta ochko'z miqdoriy belgilash rejimi

O'ta ochko'zlik rejimida matcher ochko'zlik rejimi mexanizmiga o'xshash ishlaydi. Farqi shundaki, siz matnni satr oxirigacha ushlaganingizda, orqaga qarab qidiruv bo'lmaydi. Ya'ni, o'ta ochko'zlik rejimidagi dastlabki uch bosqich ochko'zlik rejimiga o'xshash bo'ladi. Butun satrni qo'lga kiritgandan so'ng, moslashtiruvchi naqshning qolgan qismini qo'shadi va uni olingan satr bilan taqqoslaydi. Bizning misolimizda " А.++а" naqsh bilan asosiy usulni bajarishda hech qanday moslik topilmaydi. Java tilidagi oddiy iboralar - 7

Lazy kvantifikator rejimi

  1. Ushbu rejimda, dastlabki bosqichda, ochko'zlik rejimida bo'lgani kabi, naqshning birinchi belgisi bilan moslik izlanadi:

    Java tilidagi oddiy iboralar - 8
  2. Keyinchalik, u naqshdagi keyingi belgi bilan moslikni qidiradi - har qanday belgi:

    Java tilidagi oddiy iboralar - 9
  3. Ochko'zlik rejimidan farqli o'laroq, dangasa rejimi matndagi eng qisqa moslikni qidiradi, shuning uchun nuqta bilan ko'rsatilgan va matnning 6-pozitsiyasidagi belgiga mos keladigan naqshning ikkinchi belgisi bilan moslikni topgach, u Matchermatn naqshning qolgan qismiga - “ а” belgisiga mos kelishini tekshiradi.

    Java tilidagi oddiy ifodalar - 10
  4. Matndagi naqsh bilan moslik topilmaganligi sababli (matnning 7-pozitsiyasida " л" belgisi mavjud), Matcheru naqshga boshqa "har qanday belgi" qo'shadi, chunki u bir yoki bir necha marta ko'rsatilgan, va yana naqshni 5 dan 8 gacha bo'lgan pozitsiyalardagi matn bilan taqqoslaydi:

    Java tilidagi oddiy ifodalar - 11
  5. Bizning holatda, o'yin topildi, ammo matnning oxiri haligacha etib bormadi. Shuning uchun, 9-pozitsiyadan, tekshirish xuddi shunday algoritm yordamida naqshning birinchi belgisini qidirishdan boshlanadi va keyin matnning oxirigacha takrorlanadi.

    Java tilidagi oddiy iboralar - 12
Usul natijasida, main" " shablonidan foydalanganda А.+?аbiz quyidagi natijaga erishamiz: Alla Alexa Bizning misolimizdan ko'rinib turibdiki, bir xil shablon uchun turli xil kvantlash rejimlaridan foydalanganda biz turli xil natijalarga erishdik. Shuning uchun, bu xususiyatni hisobga olish va qidiruv paytida kerakli natijaga qarab kerakli rejimni tanlash kerak.

Muntazam iboralarda qochib ketadigan belgilar

Java tilidagi muntazam ifoda yoki aniqrogʻi uning dastlabki koʻrinishi string literal yordamida koʻrsatilganligi sababli, Java spetsifikatsiyasining satr literallari bilan bogʻliq qoidalarini hisobga olish kerak. Jumladan, \Java manba kodidagi string literalidagi teskari qiyshiq chiziqli “ ” belgisi kompilyatorni undan keyingi belgi maxsus belgi ekanligi va maxsus tarzda talqin qilinishi kerakligi haqida ogohlantiruvchi qochish belgisi sifatida talqin etiladi. Masalan:
String s = "The root directory is \nWindows";//wrap Windows to a new line
String s = "The root directory is \u00A7Windows";//insert paragraph character before Windows
Shuning uchun, muntazam ifodani tavsiflovchi va " " belgisini ishlatadigan satr literallarida \(masalan, metabelgilar uchun) Java bayt-kod kompilyatori uni boshqacha talqin qilmasligi uchun uni ikki barobarga oshirish kerak . Masalan:
String regex = "\\s"; // template for searching for space characters
String regex = "\"Windows\""; // pattern to search for the string "Windows"
Ikki teskari chiziq belgisi, agar biz ularni "muntazam" belgilar sifatida ishlatishni rejalashtirsak, maxsus belgilardan qochish uchun ham ishlatilishi kerak. Masalan:
String regex = "How\\?"; // template for searching the string "How?"

Pattern sinfining usullari

Sinfda Patternmuntazam iboralar bilan ishlashning boshqa usullari mavjud: String pattern()– obyekt yaratilgan oddiy ifodaning asl satr tasvirini qaytaradi Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)– regex parametrida o‘tkazilgan muntazam ifodani parametrda o‘tkazilgan matnga nisbatan tekshirish imkonini beradi input. Qaytaradi: rost – matn naqshga mos kelsa; noto'g'ri - aks holda; Misol:
System.out.println(Pattern.matches("A.+a","Alla"));//true
System.out.println(Pattern.matches("A.+a","Egor Alla Alexander"));//false
int flags()- flagsshablon yaratilganda o'rnatilgan parametr qiymatlarini qaytaradi yoki agar ushbu parametr o'rnatilmagan bo'lsa, 0 ni qaytaradi. Misol:
Pattern pattern = Pattern.compile("abc");
System.out.println(pattern.flags());// 0
Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE);
System.out.println(pattern.flags());// 2
String[] split(CharSequence text, int limit)– parametr sifatida berilgan matnni elementlar massiviga ajratadi String. Parametr limitmatnda qidiriladigan mosliklarning maksimal sonini aniqlaydi:
  • qachon limit>0– gugurtlarni qidirish limit-1amalga oshiriladi;
  • at limit<0– matndagi barcha mosliklarni qidiradi
  • qachon limit=0– matndagi barcha mosliklarni qidiradi, massiv oxiridagi bo‘sh satrlar o‘chiriladi;
Misol:
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("\\s");
    String[] strings = pattern.split(text,2);
    for (String s : strings) {
        System.out.println(s);
    }
    System.out.println("---------");
    String[] strings1 = pattern.split(text);
    for (String s : strings1) {
        System.out.println(s);
    }
}
Konsol chiqishi: Egor Alla Anna -------- Egor Alla AnnaMatcher Biz quyida ob'ekt yaratish uchun boshqa sinf usulini ko'rib chiqamiz.

Matcher sinf usullari

Matchernaqshlarni qidirish uchun ob'ekt yaratilgan sinfdir. Matcher- bu "qidiruv mexanizmi", muntazam iboralarning "motori". Qidiruv uchun unga ikkita narsa berilishi kerak: qidiruv namunasi va qidirish uchun "manzil". Ob'ektni yaratish uchun Matchersinfda quyidagi usul taqdim etiladi Pattern: рublic Matcher matcher(CharSequence input) Argument sifatida usul qidiruv amalga oshiriladigan belgilar ketma-ketligini oladi. Bu interfeysni amalga oshiradigan sinflar ob'ektlari CharSequence. StringFaqatgina emas , balki StringBuffer, StringBuilder, Segmentva argument sifatida ham o'tishingiz mumkin CharBuffer. Qidiruv shabloni - Patternbu usul chaqiriladigan sinf ob'ekti matcher. Moslashtiruvchi yaratish misoli:
Pattern p = Pattern.compile("a*b");// compiled the regular expression into a view
Matcher m = p.matcher("aaaaab");//created a search engine in the text “aaaaab” using the pattern "a*b"
Endilikda “qidiruv mexanizmimiz” yordamida biz mosliklarni qidirishimiz, matndagi moslik o‘rnini aniqlashimiz va sinf usullaridan foydalangan holda matnni almashtirishimiz mumkin. Usul boolean find()naqsh bilan matndagi keyingi moslikni qidiradi. Ushbu usul va sikl operatoridan foydalanib, siz butun matnni voqea modeliga muvofiq tahlil qilishingiz mumkin (hodisa sodir bo'lganda kerakli operatsiyalarni bajarish - matndan moslikni topish). Masalan, ushbu sinfning usullaridan foydalanib, matndagi moslik o'rinlarini aniqlashingiz mumkin va usullardan foydalanib int start(), matndagi moslikni boshqa almashtirish matni bilan almashtirishingiz mumkin. Misol: int end()String replaceFirst(String replacement)String replaceAll(String replacement)
public static void main(String[] args) {
    String text = "Egor Alla Anna";
    Pattern pattern = Pattern.compile("A.+?a");

    Matcher matcher = pattern.matcher(text);
    while (matcher.find()) {
        int start=matcher.start();
        int end=matcher.end();
        System.out.println("Match found" + text.substring(start,end) + " с "+ start + " By " + (end-1) + "position");
    }
    System.out.println(matcher.replaceFirst("Ira"));
    System.out.println(matcher.replaceAll("Olga"));
    System.out.println(text);
}
Dastur chiqishi: Gugurt topildi Alla 5 dan 8 ta pozitsiyalar Anna 10 dan 13 gacha pozitsiyalar topildi Egor Ira Anna Egor Olga Olga Egor Alla Anna Misoldan ko'rinib turibdiki, usullar yangi ob'ektni - satrni replaceFirstyaratadi . shablon bilan mos keladiganlar argument sifatida usulga uzatiladigan matn bilan almashtiriladigan manba matndir. Bundan tashqari, usul faqat birinchi o'yinni va testdagi barcha o'yinlarni almashtiradi. Asl matn o'zgarishsiz qoladi. Boshqa sinf usullaridan foydalanish , shuningdek, muntazam iboralar misollarini ushbu maqolalar seriyasida topish mumkin . Matn bilan ishlashda oddiy iboralar bilan eng keng tarqalgan operatsiyalar sinflardan olingan va . Bular , , , kabi usullardir . Lekin, aslida, "kaput ostida" ular va dan foydalanadilar . Shuning uchun, agar keraksiz kod yozmasdan, matnni almashtirish yoki dasturdagi satrlarni solishtirish kerak bo'lsa, . Agar sizga ilg'or qobiliyatlar kerak bo'lsa, sinflar haqida o'ylang va . replaceAllStringreplaceFirstreplaceAllMatcherPatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

Xulosa

Muntazam ifoda Java dasturida qoidalar bilan belgilangan naqshga mos keladigan satrlar yordamida tasvirlangan. Kod ishga tushganda, Java ushbu qatorni sinf ob'ektiga qayta kompilyatsiya qiladi va matndagi mosliklarni topish uchun Patternsinf ob'ektidan foydalanadi . MatcherBoshida aytganimdek, muntazam iboralar ko'pincha keyinroq chetga qo'yiladi, ular qiyin mavzu hisoblanadi. Biroq, agar siz sintaksis, metabelgilar, qochish asoslarini tushunsangiz va muntazam iboralar misollarini o'rgansangiz, ular birinchi qarashda ko'rinadiganidan ancha sodda bo'lib chiqadi.
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION