JavaRush /Java Blog /Random-TL /Mga Regular na Expression sa Java (RegEx)

Mga Regular na Expression sa Java (RegEx)

Nai-publish sa grupo
Ang mga regular na expression ay isang paksa na madalas ipagpaliban ng mga programmer, kahit na ang mga may karanasan, hanggang mamaya. Gayunpaman, ang karamihan sa mga developer ng Java ay maaga o huli ay kailangang harapin ang pagproseso ng teksto. Kadalasan - na may mga operasyon sa paghahanap sa teksto at pag-edit. Kung walang mga regular na expression, ang produktibo at compact na code ng programa na nauugnay sa pagpoproseso ng teksto ay hindi maiisip. Kaya itigil na ang pagpapaliban, harapin natin ang mga "regular" ngayon. Ito ay hindi isang mahirap na gawain.

Ano ang RegEx regular expression?

Sa katunayan, ang isang regular na expression (RegEx sa Java) ay isang pattern para sa paghahanap ng isang string sa text. Sa Java, ang unang representasyon ng pattern na ito ay palaging isang string, iyon ay, isang object ng String class. Gayunpaman, walang anumang string ang maaaring i-compile sa isang regular na expression, tanging ang mga sumusunod sa mga patakaran para sa pagsulat ng isang regular na expression - ang syntax na tinukoy sa detalye ng wika. Upang magsulat ng isang regular na expression, ginagamit ang mga alphabetic at numeric na character, pati na rin ang mga metacharacter - mga character na may espesyal na kahulugan sa syntax ng mga regular na expression. Halimbawa:
String regex = "java"; // string template "java";
String regex = "\\d{3}"; // string template of three numeric characters;

Paglikha ng Mga Regular na Ekspresyon sa Java

Upang lumikha ng RegEx sa Java, kailangan mong sundin ang dalawang simpleng hakbang:
  1. isulat ito bilang isang string gamit ang regular na expression syntax;
  2. ipunin ang string na ito sa isang regular na expression;
Ang pagtatrabaho sa mga regular na expression sa anumang Java program ay nagsisimula sa paglikha ng class object Pattern. Upang gawin ito, kailangan mong tawagan ang isa sa dalawang static na pamamaraan na magagamit sa klase compile. Ang unang paraan ay tumatagal ng isang argument - isang string literal ng isang regular na expression, at ang pangalawa - kasama ang isa pang parameter na nag-o-on sa mode para sa paghahambing ng template sa teksto:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Ang listahan ng mga posibleng halaga ng parameter flagsay tinukoy sa klase Patternat magagamit sa amin bilang mga static na variable ng klase. Halimbawa:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//searching for matches with the pattern will be done case-insensitively.
Mahalaga, ang klase Patternay isang regular na tagabuo ng expression. Sa ilalim ng hood, ang pamamaraan compileay tumatawag sa pribadong constructor ng klase Patternupang lumikha ng isang pinagsama-samang view. Ang pamamaraang ito ng paglikha ng isang halimbawa ng template ay ipinatupad na may layuning gawin ito bilang isang hindi nababagong bagay. Kapag lumilikha, isinasagawa ang isang syntax check ng regular na expression. Kung may mga error sa linya, bubuo ng exception PatternSyntaxException.

Syntax ng regular na expression

Nakabatay ang syntax ng regular na expression sa paggamit ng mga simbolo <([{\^-=$!|]})?*+.>, na maaaring isama sa mga alphabetic na character. Depende sa kanilang tungkulin, maaari silang nahahati sa ilang mga grupo:
1. Metacharacter para sa pagtutugma ng mga hangganan ng linya o teksto
Metacharacter Layunin
^ simula ng linya
$ dulo ng linya
\b hangganan ng salita
\B hindi limitasyon ng salita
\A simula ng input
\G pagtatapos ng nakaraang laban
\Z pagtatapos ng input
\z pagtatapos ng input
2. Metacharacter para sa paghahanap ng mga klase ng character
Metacharacter Layunin
\d digital na simbolo
\D hindi numeric na character
\s karakter sa espasyo
\S character na hindi whitespace
\w alphanumeric na character o underscore
\W anumang karakter maliban sa alpabeto, numeric, o underscore
. anumang karakter
3. Metacharacter para sa paghahanap ng mga simbolo sa pag-edit ng teksto
Metacharacter Layunin
\t karakter ng tab
\n bagong linyang karakter
\r karakter ng pagbabalik ng karwahe
\f pumunta sa bagong pahina
\u0085 karakter sa susunod na linya
\u 2028 character ng line separator
\u 2029 simbolo ng separator ng talata
4. Metacharacter para sa pagpapangkat ng mga character
Metacharacter Layunin
[a B C] alinman sa nabanggit (a, b, o c)
[^abc] anuman maliban sa mga nakalista (hindi a, b, c)
[a-zA-Z] pagsasama ng saklaw (ang mga Latin na character a hanggang z ay case insensitive)
[ad[mp]] pagsasama-sama ng mga character (a hanggang d at m hanggang p)
[az&&[def]] intersection ng mga simbolo (mga simbolo d,e,f)
[az&&[^bc]] pagbabawas ng mga character (character a, dz)
5. Metasymbols upang ipahiwatig ang bilang ng mga character - mga quantifier. Ang quantifier ay palaging kasunod ng isang karakter o grupo ng mga character.
Metacharacter Layunin
? isa o wala
* zero o higit pang beses
+ isa o higit pang beses
{n} n beses
{n,} n beses o higit pa
{n,m} hindi bababa sa n beses at hindi hihigit sa m beses

Matakaw na quantifier mode

Ang isang espesyal na tampok ng mga quantifier ay ang kakayahang gamitin ang mga ito sa iba't ibang mga mode: sakim, sobrang sakim at tamad. Naka-on ang extra-greedy mode+ sa pamamagitan ng pagdaragdag ng simbolo na “ ” pagkatapos ng quantifier, at ang lazy mode sa pamamagitan ng pagdaragdag ng simbolo na “ ?“. Halimbawa:
"A.+a" // greedy mode
"A.++a" // over-greedy mode
"A.+?a" // lazy mode
Gamit ang template na ito bilang halimbawa, subukan nating maunawaan kung paano gumagana ang mga quantifier sa iba't ibang mga mode. Bilang default, gumagana ang quantifier sa greedy mode. Nangangahulugan ito na hinahanap nito ang pinakamahabang posibleng tugma sa string. Bilang resulta ng pagpapatakbo ng code na ito:
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()));
    }
}
makukuha natin ang sumusunod na output: Alla Alexa Ang algorithm ng paghahanap para sa isang naibigay na pattern na " А.+а" ay ginagawa sa sumusunod na pagkakasunud-sunod:
  1. Sa ibinigay na pattern, ang unang character ay ang Russian letter character А. Matchertumutugma ito sa bawat karakter ng teksto, simula sa posisyong zero. Sa posisyong zero sa aming teksto ay mayroong isang simbolo Е, kaya Matcherdumadaan ito sa mga character sa teksto nang sunud-sunod hanggang sa matugunan nito ang isang tugma sa pattern. Sa aming halimbawa, ito ang simbolo sa posisyon No. 5.

    Mga Regular na Ekspresyon sa Java - 2
  2. Pagkatapos mahanap ang isang tugma sa unang character ng pattern, Matchersinusuri nito ang tugma sa pangalawang character ng pattern. Sa aming kaso, ito ang simbolo na " .", na kumakatawan sa anumang karakter.

    Mga Regular na Ekspresyon sa Java - 3

    Sa ikaanim na posisyon ay ang simbolo ng titik л. Siyempre, tumutugma ito sa pattern na "anumang karakter".

  3. Matchernagpapatuloy sa pagsuri sa susunod na karakter mula sa pattern. Sa aming template, ito ay tinukoy gamit ang “ .+” quantifier. Dahil ang bilang ng mga pag-uulit ng "anumang character" sa pattern ay isa o higit pang beses, Matcherito ay kukuha ng susunod na character mula sa string at sinusuri ito para sa pagsunod sa pattern, hangga't ang "anumang character" na kondisyon ay natutugunan, sa aming halimbawa - hanggang sa dulo ng linya ( mula sa posisyon No. 7 - No. 18 ng teksto).

    Mga Regular na Ekspresyon sa Java - 4

    Sa katunayan, Matcherkinukuha nito ang buong linya hanggang sa dulo - dito na nagpapakita ng sarili nitong "kasakiman".

  4. Matapos Matchermaabot ang dulo ng text at tapusin ang pagsuri para sa “ А.+” na bahagi ng pattern, sinisimulan ng Matcher na suriin ang natitirang pattern - ang character ng titik а. Dahil ang teksto sa pasulong na direksyon ay natapos na, ang tseke ay nangyayari sa pabalik na direksyon, simula sa huling karakter:

    Mga Regular na Ekspresyon sa Java - 5
  5. Matcher"naaalala" ang bilang ng mga pag-uulit sa pattern na " .+" kung saan naabot nito ang dulo ng teksto, kaya binabawasan nito ang bilang ng mga pag-uulit ng isa at sinusuri ang pattern para sa teksto hanggang sa makita ang isang tugma: Mga Regular na Ekspresyon sa Java - 6

Ultra-matakaw na quantifier mode

Sa super-greedy mode, ang matcher ay gumagana katulad ng greedy mode mechanism. Ang pagkakaiba ay kapag kumuha ka ng teksto hanggang sa dulo ng linya, walang paghahanap pabalik. Ibig sabihin, ang unang tatlong yugto sa super-greedy mode ay magiging katulad ng greedy mode. Pagkatapos makuha ang buong string, idaragdag ng matcher ang natitirang pattern at ihahambing ito sa nakuhang string. Sa aming halimbawa, kapag isinasagawa ang pangunahing pamamaraan na may pattern na " А.++а", walang makikitang mga tugma. Mga Regular na Ekspresyon sa Java - 7

Tamad na quantifier mode

  1. Sa mode na ito, sa paunang yugto, tulad ng sa matakaw na mode, ang isang tugma ay hinahangad na may unang karakter ng pattern:

    Mga Regular na Ekspresyon sa Java - 8
  2. Susunod, naghahanap ito ng tugma sa susunod na karakter sa pattern - anumang karakter:

    Mga Regular na Ekspresyon sa Java - 9
  3. Hindi tulad ng greedy mode, ang lazy mode ay naghahanap ng pinakamaikling tugma sa text, kaya pagkatapos makahanap ng tugma sa pangalawang character ng pattern, na tinukoy ng isang tuldok at tumutugma sa character sa posisyon No. 6 ng teksto, ito Matchersusuriin kung ang teksto ay tumutugma sa natitirang pattern - ang karakter na " а" .

    Mga Regular na Ekspresyon sa Java - 10
  4. Dahil ang isang tugma sa pattern sa teksto ay hindi natagpuan (sa posisyon No. 7 sa teksto ay may simbolo na " " л), Matchernagdaragdag ito ng isa pang "anumang character" sa pattern, dahil ito ay tinukoy bilang isa o higit pang beses, at muling inihambing ang pattern sa teksto sa mga posisyon na may No. 5 hanggang No. 8:

    Mga Regular na Ekspresyon sa Java - 11
  5. Sa aming kaso, natagpuan ang isang tugma, ngunit ang dulo ng teksto ay hindi pa naabot. Samakatuwid, mula sa posisyon No. 9, ang tseke ay nagsisimula sa pamamagitan ng paghahanap para sa unang karakter ng pattern gamit ang isang katulad na algorithm at pagkatapos ay uulit hanggang sa katapusan ng teksto.

    Mga Regular na Ekspresyon sa Java - 12
Bilang resulta ng pamamaraan, mainkapag ginagamit ang А.+?аtemplate na " ", makukuha natin ang sumusunod na resulta: Alla Alexa Gaya ng makikita mula sa aming halimbawa, kapag gumagamit ng iba't ibang mga mode ng quantifier para sa parehong template, nakakuha kami ng iba't ibang mga resulta. Samakatuwid, kinakailangang isaalang-alang ang tampok na ito at piliin ang nais na mode depende sa nais na resulta sa panahon ng paghahanap.

Pagtakas sa mga character sa mga regular na expression

Dahil ang isang regular na expression sa Java, o mas tiyak ang paunang representasyon nito, ay tinukoy gamit ang string literal, kinakailangang isaalang-alang ang mga panuntunan ng Java specification na nauugnay sa string literals. Sa partikular, ang backslash na character na " \" sa mga string literal sa Java source code ay binibigyang-kahulugan bilang isang escape character na nag-aalerto sa compiler na ang character na kasunod nito ay isang espesyal na character at dapat bigyang-kahulugan sa isang espesyal na paraan. Halimbawa:
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
Samakatuwid, sa mga literal na string na naglalarawan ng isang regular na expression at gumagamit ng \karakter na " " (halimbawa, para sa mga metacharacter), dapat itong doblehin upang hindi ito mabigyang-kahulugan ng Java bytecode compiler nang iba. Halimbawa:
String regex = "\\s"; // template for searching for space characters
String regex = "\"Windows\""; // pattern to search for the string "Windows"
Dapat ding gamitin ang double backslash na character para makatakas sa mga espesyal na character kung plano naming gamitin ang mga ito bilang mga "regular" na character. Halimbawa:
String regex = "How\\?"; // template for searching the string "How?"

Mga pamamaraan ng klase ng Pattern

Ang klase Patternay may iba pang mga pamamaraan para sa pagtatrabaho sa mga regular na expression: String pattern()– ibinabalik ang orihinal na representasyon ng string ng regular na expression kung saan nilikha ang object Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)– nagbibigay-daan sa iyong suriin ang regular na expression na ipinasa sa regex parameter laban sa text na ipinasa sa parameter input. Returns: true – kung ang teksto ay tumutugma sa pattern; mali – kung hindi man; Halimbawa:
System.out.println(Pattern.matches("A.+a","Alla"));//true
System.out.println(Pattern.matches("A.+a","Egor Alla Alexander"));//false
int flags()– ibinabalik ang flagsmga halaga ng parameter ng template na itinakda noong ito ay nilikha, o 0 kung hindi naitakda ang parameter na ito. Halimbawa:
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)– hinahati ang tekstong ipinasa bilang isang parameter sa isang hanay ng mga elemento String. Tinutukoy ng parameter limitang maximum na bilang ng mga tugma na hinahanap sa text:
  • kapag limit>0– ang paghahanap para sa limit-1mga tugma ay ginanap;
  • sa limit<0– hinahanap ang lahat ng tugma sa teksto
  • kapag limit=0– hinahanap ang lahat ng mga tugma sa teksto, habang ang mga walang laman na linya sa dulo ng array ay itinatapon;
Halimbawa:
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);
    }
}
Output ng console: Egor Alla Anna -------- Egor Alla Anna Isasaalang-alang namin ang isa pang paraan ng klase para sa paggawa ng object Matchersa ibaba.

Mga pamamaraan ng klase ng matcher

Matcheray isang klase kung saan nilikha ang isang bagay upang maghanap ng mga pattern. Matcher– ito ay isang “search engine”, isang “engine” ng mga regular na expression. Upang maghanap, kailangan siyang bigyan ng dalawang bagay: isang pattern ng paghahanap at isang "address" na hahanapin. Upang lumikha ng isang bagay, Matcherang sumusunod na pamamaraan ay ibinigay sa klase Pattern: рublic Matcher matcher(CharSequence input) Bilang isang argumento, ang pamamaraan ay tumatagal ng isang pagkakasunod-sunod ng mga character kung saan ang paghahanap ay isasagawa. Ito ay mga bagay ng mga klase na nagpapatupad ng interface CharSequence. StringMaaari kang pumasa hindi lamang , kundi pati na rin StringBuffer, StringBuilder, Segmentat bilang isang argumento CharBuffer. Ang template ng paghahanap ay ang class object Patternkung saan ang pamamaraan ay tinatawag na matcher. Halimbawa ng paglikha ng isang matcher:
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"
Ngayon, sa tulong ng aming "search engine," maaari kaming maghanap ng mga tugma, alamin ang posisyon ng tugma sa teksto, at palitan ang teksto gamit ang mga pamamaraan ng klase. Ang pamamaraan boolean find()ay naghahanap para sa susunod na tugma sa teksto na may pattern. Gamit ang pamamaraang ito at ang loop operator, maaari mong pag-aralan ang buong teksto ayon sa modelo ng kaganapan (isagawa ang mga kinakailangang operasyon kapag naganap ang isang kaganapan - paghahanap ng isang tugma sa teksto). Halimbawa, gamit ang mga pamamaraan ng klase na ito, matutukoy int start()mo ang mga posisyon ng tugma sa teksto, at gamit ang mga pamamaraan , palitan ang mga tugma sa teksto ng isa pang kapalit na teksto. Halimbawa: 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);
}
Output ng programa: Nahanap ang isang tugma Alla mula 5 hanggang 8 na posisyon Nahanap ang isang tugma Anna mula 10 hanggang 13 na posisyon Egor Ira Anna Egor Olga Olga Egor Alla Anna Mula sa halimbawa ay malinaw na ang mga pamamaraan replaceFirstay lumikha replaceAllng isang bagong bagay String- isang string, na kung saan ay ang source text kung saan ang mga tugma sa template ay pinapalitan ng text na ipinasa sa method bilang argumento. replaceFirstBukod dito, pinapalitan lamang ng pamamaraan ang unang tugma, at replaceAlllahat ng mga tugma sa pagsubok. Ang orihinal na teksto ay nananatiling hindi nagbabago. Ang paggamit ng iba pang mga pamamaraan ng klase Matcher, pati na rin ang mga halimbawa ng mga regular na expression, ay matatagpuan sa seryeng ito ng mga artikulo . Ang pinakakaraniwang mga operasyon na may mga regular na expression kapag nagtatrabaho sa teksto ay mula sa mga klase Patternat Matchernakapaloob sa String. Ito ay mga pamamaraan tulad ng split, matches, replaceFirst, replaceAll. Ngunit sa katunayan, "sa ilalim ng talukbong" ginagamit nila ang Patternat Matcher. Samakatuwid, kung kailangan mong palitan ang teksto o ihambing ang mga string sa isang programa nang hindi nagsusulat ng hindi kinakailangang code, gamitin ang mga pamamaraan ng String. Kung kailangan mo ng mga advanced na kakayahan, isipin ang tungkol sa mga klase Patternat Matcher.

Konklusyon

Ang isang regular na expression ay inilalarawan sa isang Java program gamit ang mga string na tumutugma sa isang pattern na tinukoy ng mga panuntunan. Kapag tumakbo ang code, muling kino-compile ng Java ang string na ito sa isang object ng klase Patternat ginagamit ang object ng klase Matcherupang maghanap ng mga tugma sa teksto. Tulad ng sinabi ko sa simula, ang mga regular na expression ay madalas na isinantabi para sa ibang pagkakataon, na itinuturing na isang mahirap na paksa. Gayunpaman, kung nauunawaan mo ang mga pangunahing kaalaman sa syntax, metacharacter, pagtakas, at pag-aaral ng mga halimbawa ng mga regular na expression, lumalabas na mas simple ang mga ito kaysa sa tila sa unang tingin.
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION