JavaRush /Java Blogu /Random-AZ /Java-da müntəzəm ifadələr (RegEx)

Java-da müntəzəm ifadələr (RegEx)

Qrupda dərc edilmişdir
Daimi ifadələr proqramçıların, hətta təcrübəli olanların da çox vaxt sonraya qoyduğu bir mövzudur. Bununla belə, əksər Java tərtibatçıları gec-tez mətn emalı ilə məşğul olacaqlar. Çox vaxt - mətndə və redaktədə axtarış əməliyyatları ilə. Müntəzəm ifadələr olmadan, mətn emalı ilə əlaqəli məhsuldar və yığcam proqram kodu sadəcə ağlasığmazdır. Odur ki, bunu təxirə salmağı dayandırın, gəlin indi “müntəzəmlərlə” məşğul olaq. Bu elə də çətin iş deyil.

RegEx müntəzəm ifadəsi nədir?

Əslində, müntəzəm ifadə (Java-da RegEx) mətndə sətir axtarışı üçün nümunədir. Java-da bu nümunənin ilkin təsviri həmişə sətirdir, yəni String sinifinin obyektidir. Bununla belə, hər hansı bir sətir müntəzəm ifadəyə tərtib edilə bilməz, yalnız müntəzəm ifadənin yazılması qaydalarına - dil spesifikasiyasında müəyyən edilmiş sintaksisə əməl edənlər. Normal ifadəni yazmaq üçün əlifba və ədədi simvollardan, həmçinin metasimvollardan - müntəzəm ifadələrin sintaksisində xüsusi məna kəsb edən simvollardan istifadə olunur. Misal üçün:
String regex = "java"; // string template "java";
String regex = "\\d{3}"; // string template of three numeric characters;

Java-da müntəzəm ifadələrin yaradılması

Java-da RegEx yaratmaq üçün iki sadə addımı yerinə yetirməlisiniz:
  1. müntəzəm ifadə sintaksisindən istifadə edərək onu sətir kimi yazın;
  2. bu sətri müntəzəm ifadəyə tərtib edin;
İstənilən Java proqramında müntəzəm ifadələrlə işləmək sinif obyektinin yaradılması ilə başlayır Pattern. Bunu etmək üçün sinifdə mövcud olan iki statik metoddan birini çağırmalısınız compile. Birinci üsul bir arqument alır - müntəzəm ifadənin sətir hərfi, ikincisi - üstəgəl şablonu mətnlə müqayisə etmək rejimini işə salan başqa bir parametr:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Mümkün parametr dəyərlərinin siyahısıflags sinifdə müəyyən edilir Patternvə statik sinif dəyişənləri kimi bizim üçün mövcuddur. Misal üçün:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//searching for matches with the pattern will be done case-insensitively.
Əsasən, sinif Patternmüntəzəm ifadə konstruktorudur. Başlıq altında, metod tərtib edilmiş bir görünüş yaratmaq üçün compilesinfin şəxsi konstruktorunu çağırır . PatternŞablon nümunəsinin yaradılmasının bu üsulu onu dəyişməz obyekt kimi yaratmaq məqsədi ilə həyata keçirilir. Yaradarkən müntəzəm ifadənin sintaksisi yoxlanılır. Sətirdə səhvlər varsa, istisna yaradılır PatternSyntaxException.

Adi ifadə sintaksisi

<([{\^-=$!|]})?*+.>Daimi ifadə sintaksisi əlifba simvolları ilə birləşdirilə bilən simvolların istifadəsinə əsaslanır . Rollarından asılı olaraq onları bir neçə qrupa bölmək olar:
1. Uyğun sətir sərhədləri və ya mətn üçün meta-simvollar
Metaxarakter Məqsəd
^ xəttin başlanğıcı
$ xəttin sonu
\b söz sərhədi
\B söz həddi deyil
\A girişin başlanğıcı
\G əvvəlki matçın sonu
\Z girişin sonu
\z girişin sonu
2. Xarakter siniflərinin axtarışı üçün meta-simvollar
Metaxarakter Məqsəd
\d rəqəmsal simvol
\D rəqəmsiz xarakter
\s kosmik xarakter
\S boşluq olmayan xarakter
\w alfasayısal simvol və ya alt xətt
\W əlifba, rəqəm və ya alt xəttdən başqa hər hansı simvol
. hər hansı bir xarakter
3. Mətn redaktə simvollarının axtarışı üçün metasimvollar
Metaxarakter Məqsəd
\t nişan simvolu
\n yeni sətir simvolu
\r vaqonun qaytarılması xarakteri
\f yeni səhifəyə keçin
\u0085 növbəti sətir simvolu
\u 2028 xətt ayırıcı xarakter
\u 2029 paraqraf ayırıcı simvol
4. Simvolların qruplaşdırılması üçün metasimvollar
Metaxarakter Məqsəd
[a B C] yuxarıdakılardan hər hansı biri (a, b və ya c)
[^abc] sadalananlardan başqa (a, b, c deyil)
[a-zA-Z] diapazonun birləşməsi (a-dan z-yə qədər olan Latın hərfləri hərflərə həssasdır)
[reklam[mp]] simvolların birləşməsi (a-dan d və m-dən p)
[az&&[def]] simvolların kəsişməsi (d,e,f simvolları)
[az&&[^bc]] simvolların çıxarılması (a, dz simvolları)
5. Simvolların sayını göstərən metasimvollar - kəmiyyət göstəriciləri. Kəmiyyət göstəricisi həmişə simvoldan və ya simvollar qrupundan sonra gəlir.
Metaxarakter Məqsəd
? bir və ya itkin
* sıfır və ya daha çox dəfə
+ bir və ya bir neçə dəfə
{n} n dəfə
{n,} n dəfə və ya daha çox
{n,m} n dəfədən az və m dəfədən çox olmamalıdır

Açgözlü kəmiyyət göstəricisi rejimi

Kəmiyyət göstəricilərinin xüsusi xüsusiyyəti onlardan müxtəlif rejimlərdə istifadə etmək qabiliyyətidir: acgöz, super acgöz və tənbəl. Kəmiyyət göstəricisindən sonra “ ” işarəsi, tənbəl rejim isə “ “ işarəsi əlavə edilməklə əlavə acgözlük rejimi işə salınır . Misal üçün: +?
"A.+a" // greedy mode
"A.++a" // over-greedy mode
"A.+?a" // lazy mode
Nümunə olaraq bu şablondan istifadə edərək, kəmiyyət göstəricilərinin müxtəlif rejimlərdə necə işlədiyini anlamağa çalışaq. Varsayılan olaraq, kəmiyyət göstəricisi acgöz rejimdə işləyir. Bu o deməkdir ki, o, sətirdə mümkün olan ən uzun uyğunluğu axtarır. Bu kodun işlədilməsi nəticəsində:
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 aşağıdakı nəticəni alacağıq: Alla Alexa Verilmiş nümunə üçün axtarış alqoritmi " А.+а" aşağıdakı ardıcıllıqla yerinə yetirilir:
  1. Verilmiş nümunədə birinci simvol rus hərfinin simvoludur А. Matcheronu sıfır mövqeyindən başlayaraq mətnin hər simvoluna uyğunlaşdırır. Mətnimizdə sıfır mövqedə bir simvol var Е, buna görə də Matchernaxışa uyğun gələnə qədər mətndəki simvolları ardıcıl olaraq keçir. Bizim nümunəmizdə bu, 5 nömrəli mövqedəki simvoldur.

    Java-da müntəzəm ifadələr - 2
  2. Naxışın birinci simvolu ilə uyğunluq tapıldıqdan sonra Matchero, naxışın ikinci simvolu ilə uyğunluğu yoxlayır. .Bizim vəziyyətimizdə bu, hər hansı simvolu ifadə edən “ ” simvoludur .

    Java-da müntəzəm ifadələr - 3

    Altıncı mövqedə hərf simvolu var л. Əlbəttə ki, "hər hansı bir xarakter" nümunəsinə uyğun gəlir.

  3. Matchernümunədən növbəti simvolu yoxlamağa keçir. Şablonumuzda “ .+” kəmiyyət göstəricisi ilə müəyyən edilmişdir. Nümunədə “istənilən simvol”un təkrar sayı bir və ya bir neçə dəfə olduğu üçün Matchero, növbə ilə sətirdən növbəti simvolu götürür və “hər hansı bir simvol” şərti yerinə yetirildiyi müddətcə onun naxışa uyğunluğunu yoxlayır. nümunəmizdə - sətrin sonuna qədər (mətnin 7-ci mövqeyindən - No18).

    Java-da müntəzəm ifadələr - 4

    Əslində, Matchero, bütün xətti sona qədər tutur - "həsisliyi" burada özünü göstərir.

  4. MatcherMətnin sonuna çatdıqdan və naxışın “ ” hissəsinin yoxlanılmasını bitirdikdən sonra А.+Matcher nümunənin qalan hissəsini - hərf simvolunu yoxlamağa başlayır а. İrəli istiqamətdə mətn bitdiyi üçün yoxlama sonuncu simvoldan başlayaraq tərs istiqamətdə baş verir:

    Java-da müntəzəm ifadələr - 5
  5. Matcher.+Mətnin sonuna çatdığı " " nümunəsində təkrarların sayını "xatırlayır" , buna görə də təkrarların sayını bir azaldır və uyğunluq tapılana qədər mətn üçün nümunəni yoxlayır:Java-da müntəzəm ifadələr - 6

Ultra acgöz kəmiyyət göstəricisi rejimi

Super acgöz rejimdə uyğunlaşdırıcı acgöz rejim mexanizminə bənzər şəkildə işləyir. Fərq ondadır ki, mətni sətrin sonuna qədər tutduqda geriyə doğru axtarış aparılmır. Yəni super acgöz rejimdə ilk üç mərhələ acgözlük rejiminə bənzəyəcək. Bütün simi tutduqdan sonra uyğunlaşdırıcı nümunənin qalan hissəsini əlavə edir və onu tutulan simlə müqayisə edir. Bizim nümunəmizdə əsas metodu " А.++а" nümunəsi ilə icra edərkən heç bir uyğunluq tapılmayacaq. Java-da müntəzəm ifadələr - 7

Tənbəl kəmiyyət göstəricisi rejimi

  1. Bu rejimdə, ilkin mərhələdə, acgöz rejimdə olduğu kimi, nümunənin ilk simvolu ilə uyğunluq axtarılır:

    Java-da müntəzəm ifadələr - 8
  2. Sonra, naxışda növbəti simvol ilə uyğunluğu axtarır - istənilən simvol:

    Java-da müntəzəm ifadələr - 9
  3. Acgöz rejimdən fərqli olaraq, tənbəl rejim mətndə ən qısa uyğunluğu axtarır, ona görə də nümunənin nöqtə ilə göstərilən və mətnin 6-cı mövqeyində simvola uyğun gələn ikinci simvolu ilə uyğunluğu tapdıqdan sonra Matchermətnin nümunənin qalan hissəsinə - “ а” simvoluna uyğun olub olmadığını yoxlayacaq.

    Java-da müntəzəm ifadələr - 10
  4. Mətndəki naxışla uyğunluq tapılmadığından (mətndə 7-ci mövqedə “ л“ işarəsi var), Matchero, bir və ya bir neçə dəfə göstərildiyi üçün naxışa başqa “istənilən simvol” əlavə edir, və yenidən nümunəni 5-dən 8-ə qədər olan mövqelərdəki mətnlə müqayisə edir:

    Java-da müntəzəm ifadələr - 11
  5. Bizim vəziyyətimizdə uyğunluq tapıldı, lakin mətnin sonuna hələ çatılmayıb. Buna görə də, 9-cu mövqedən yoxlama oxşar alqoritmdən istifadə edərək nümunənin birinci simvolunu axtarmaqla başlayır və sonra mətnin sonuna qədər təkrarlanır.

    Java-da müntəzəm ifadələr - 12
Metodun nəticəsi olaraq, main" " şablonundan istifadə edərkən А.+?аaşağıdakı nəticəni əldə edəcəyik: Alla Alexa Nümunəmizdən də göründüyü kimi, eyni şablon üçün müxtəlif kvanter rejimlərindən istifadə edərkən fərqli nəticələr əldə etdik. Buna görə də, bu xüsusiyyəti nəzərə almaq və axtarış zamanı istədiyiniz nəticədən asılı olaraq istədiyiniz rejimi seçmək lazımdır.

Normal ifadələrdə qaçan simvollar

Java-da müntəzəm ifadə, daha dəqiq desək, onun ilkin təsviri sətir literalından istifadə edilməklə göstərildiyi üçün Java spesifikasiyasının sətir literallarına aid qaydalarını nəzərə almaq lazımdır. Xüsusilə, \Java mənbə kodunda sətir literallarında əks kəsik işarəsi olan " " simvolu, ondan sonra gələn simvolun xüsusi simvol olduğu və xüsusi şəkildə şərh edilməli olduğu barədə kompilyatora xəbərdarlıq edən qaçış simvolu kimi şərh olunur. Misal üçün:
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
Buna görə də, müntəzəm ifadəni təsvir edən və " " simvolundan istifadə edən sətir literallarında \(məsələn, metasimvollar üçün) Java bayt kodu kompilyatorunun onu fərqli şərh etməməsi üçün ikiqat artırılmalıdır . Misal üçün:
String regex = "\\s"; // template for searching for space characters
String regex = "\"Windows\""; // pattern to search for the string "Windows"
Əgər biz onları "müntəzəm" simvol kimi istifadə etməyi planlaşdırırıqsa, xüsusi simvollardan qaçmaq üçün ikiqat tərs xətt simvolu da istifadə edilməlidir. Misal üçün:
String regex = "How\\?"; // template for searching the string "How?"

Pattern sinfinin metodları

Sinfin Patternnormal ifadələrlə işləmək üçün başqa üsulları var: String pattern()– obyektin yaradıldığı müntəzəm ifadənin orijinal sətir təsvirini qaytarır Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)– regex parametrində verilən müntəzəm ifadəni parametrdə ötürülən mətnlə müqayisə etməyə imkan verir input. Qaytarır: doğru – mətn nümunəyə uyğundursa; yalan - əks halda; Misal:
System.out.println(Pattern.matches("A.+a","Alla"));//true
System.out.println(Pattern.matches("A.+a","Egor Alla Alexander"));//false
int flags()flagsşablon yaradılarkən təyin edilmiş parametr dəyərlərini qaytarır və ya bu parametr təyin edilmədikdə 0-ı qaytarır. Misal:
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 kimi ötürülən mətni elementlər massivinə bölür String. Parametr limitmətndə axtarılan uyğunluqların maksimum sayını müəyyən edir:
  • nə vaxt limit>0– uyğunluqların axtarışı limit-1aparılır;
  • at limit<0– mətndəki bütün uyğunluqları axtarır
  • when limit=0– massivin sonundakı boş sətirlər silinərkən mətndəki bütün uyğunluqları axtarır;
Misal:
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 çıxışı: Egor Alla Anna -------- Egor Alla AnnaMatcher Aşağıda obyekt yaratmaq üçün başqa bir sinif metodunu nəzərdən keçirəcəyik.

Uyğun sinif metodları

Matchernümunələri axtarmaq üçün obyektin yaradıldığı sinifdir. Matcher– bu, “axtarış motoru”, müntəzəm ifadələrin “mühərriki”dir. Axtarmaq üçün ona iki şey verilməlidir: axtarış nümunəsi və axtarış üçün “ünvan”. Obyekt yaratmaq üçün Matchersinifdə aşağıdakı üsul təqdim olunur Pattern: рublic Matcher matcher(CharSequence input) Arqument kimi metod axtarışın aparılacağı simvollar ardıcıllığını götürür. Bunlar interfeysi həyata keçirən siniflərin obyektləridir CharSequence. Təkcə yox , Stringhəm də StringBuffer, StringBuildervə arqument kimi keçə bilərsiniz . Axtarış şablonu metodun çağırıldığı sinif obyektidir . Uyğunlaşdırıcı yaratmaq nümunəsi: SegmentCharBufferPatternmatcher
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"
İndi “axtarış sistemimizin” köməyi ilə biz uyğunluqları axtara, mətndəki uyğunluğun yerini öyrənə və sinif metodlarından istifadə edərək mətni əvəz edə bilərik. Metod boolean find()nümunə ilə mətndə növbəti uyğunluğu axtarır. Bu üsuldan və döngə operatorundan istifadə edərək, hadisə modelinə uyğun olaraq bütün mətni təhlil edə bilərsiniz (hadisə baş verəndə lazımi əməliyyatları yerinə yetirin - mətndə uyğunluğun tapılması). Məsələn, bu sinfin metodlarından istifadə edərək mətndəki uyğunluğun mövqelərini müəyyən edə, üsullardan istifadə edərək mətndəki uyğunluqları başqa əvəzedici mətnlə əvəz edə int start()bilərsiniz . Misal: 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);
}
Proqramın çıxışı: Alla 5-dən 8 mövqeyə qədər uyğunluq tapıldı Anna 10-dan 13-ə qədər mövqe tapıldı Eqor İra Anna Eqor Olqa Olqa Eqor Alla Anna Nümunədən aydın olur ki, üsullar yeni obyekt - sim replaceFirstyaradır . şablonla uyğunluqların arqument kimi metoda ötürülən mətnlə əvəz edildiyi mənbə mətndir. Üstəlik, metod yalnız ilk matçı və testdəki bütün uyğunluğu əvəz edir. Orijinal mətn dəyişməz olaraq qalır. Digər sinif metodlarının istifadəsi , eləcə də müntəzəm ifadələrin nümunələri bu məqalələr silsiləsində tapıla bilər . Mətnlə işləyərkən müntəzəm ifadələrlə ən çox görülən əməliyyatlar siniflərdəndir və . Bunlar , , , kimi üsullardır . Amma əslində "başlıq altında" və istifadə edirlər . Buna görə də, lazımsız kod yazmadan proqramda mətni əvəz etmək və ya sətirləri müqayisə etmək lazımdırsa, . Qabaqcıl imkanlara ehtiyacınız varsa, dərslər və . replaceAllStringreplaceFirstreplaceAllMatcherPatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

Nəticə

Normal ifadə Java proqramında qaydalarla müəyyən edilmiş nümunəyə uyğun gələn sətirlərdən istifadə etməklə təsvir edilir. Kod işlədiyi zaman Java bu sətri yenidən sinif obyektinə çevirir və mətndə uyğunluq tapmaq üçün Patternsinif obyektindən istifadə edir . MatcherBaşlanğıcda dediyim kimi, nizamlı ifadələr çox vaxt sonralar üçün kənara qoyulur, çətin mövzu hesab olunur. Bununla belə, sintaksis, metaxarakterlər, qaçış əsaslarını başa düşsəniz və müntəzəm ifadələrin nümunələrini öyrənsəniz, onlar ilk baxışda göründüyündən daha sadə olur.
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION