Loading...

Жолчолор менен иштөө үчүн кошмча туюнтмалар

 

Регулярдуу туюнтмалар сапты иштетүү үчүн күчтүү курал болуп саналат. Кадимки туюнтмалар сап же субсап дал келүүчү үлгүнү көрсөтүүгө мүмкүндүк берет.

 

String классынын кээ бир ыкмалары туруктуу туюнтмаларды кабыл алат жана аларды саптар менен операцияларды аткаруу үчүн колдонот.

 

бөлүү

Split() методу сапты ички саптарга бөлүү үчүн колдонулат. Ал параметр катары сапты бөлүү критерийин билдирген кадимки туюнтманы кабыл алат.

 

Мисалы, сүйлөмдү сөздөргө бөлөлү:

 String text = "FIFA will never regret it";

String[] words = text.split("\\s*(\\s|,|!|\\.)\\s*");

for(String word : words){

    System.out.println(word);

}

"\\s*(\\s|,|!|\\.)\\s*" кадимки сөз айкашы бөлүү үчүн колдонулат. "\\s" субэкспрессиясы негизинен боштукту билдирет. Жылдызча белги 0дөн чексиз санга чейин болушу мүмкүн экенин көрсөтүп турат. Башкача айтканда, биз жылдызчаны кошуп, ырааттуу боштуктардын белгисиз санын алабыз - "\\s*" (башкача айтканда, сөздөрдүн ортосунда канча боштук бар экендиги маанилүү эмес). Анын үстүнө, эч кандай боштуктар болушу мүмкүн. кашаанын ичинде белгисиз сандагы боштуктардан кийин келе турган туюнтмалардын тобун көрсөтөт. Топ бизге вертикалдуу тилке менен бөлүнгөн баалуулуктардын топтомун аныктоого мүмкүндүк берет жана субсап ошол маанилердин бирине дал келиши керек. . Башкача айтканда, "\\s|,|!|\\" тобунда. ички сап боштукка, үтүргө, илеп белгисине же чекитке дал келиши мүмкүн. Анын үстүнө чекит өзгөчө ырааттуулукту билдиргендиктен, биз чекиттин өзгөчө ырааттуулугун эмес, белгисин айтып жатканыбызды көрсөтүү үчүн чекиттин алдына сызыктарды коёбуз.

 

Стринг дал келүү. дал келет

String классынын дагы бир ыкмасы matches(), регулярдуу туюнтманы кабыл алат жана сап ушул туюнтмага дал келсе, чындыкты кайтарат. Болбосо false кайтарат.

 

Мисалы, сап телефон номерине дал келгенин текшерип көрөлү:

String input = "+12343454556";

boolean result = input.matches("(\\+*)\\d{11}");

if(result){

    System.out.println("It is a phone number");

}

else{

    System.out.println("It is not a phone number!");   

}

Бул учурда, регулярдуу туюнтма алгач "(\\+*)" тобун аныктайт. Башкача айтканда, башында плюс белгиси болушу мүмкүн, бирок ал жок болушу да мүмкүн. Андан кийин, биз кийинки 11 белги сандарга дал келеби же жокпу, карап көрөлү. "\\d" туюнтмасы сандык символду билдирет, ал эми тармал кашаадагы сан - {11} - берилген белги түрү канча жолу кайталанышы керек. Башкача айтканда, биз биринчи плюс белгиси (же ал жок болушу мүмкүн), андан кийин 11 сандык белги бара турган сапты издеп жатабыз.

 

Pattern классы

Javaнын кадимки туюнтма функцияларынын көбү java.util.regex пакетинде жайгашкан.

Регулярдуу туюнтма өзү сапта дал келүүлөрдү табуу үлгүсүн билдирет. Окшош үлгүнү көрсөтүү жана берилген үлгүгө дал келген саптын ички саптарын издөө үчүн Java Pattern жана Matcher класстарын аныктайт.

 

Жөнөкөй дал келүү үчүн Pattern классы логикалык дал келүүлөрдү (String үлгүсү, CharSequence киргизүү) статикалык ыкманы аныктайт. Киргизилген символдордун ырааттуулугу сап үлгүсүнүн үлгүсүнө толук дал келсе, бул ыкма чындыкты кайтарат:

import java.util.regex.Pattern;

 

public class StringsApp {

 

    public static void main(String[] args) {

        

        String input = "Hello";

        boolean found = Pattern.matches("Hello", input);

        if(found)

            System.out.println("Найдено");

        else

            System.out.println("Не найдено");

    }  

}

Бирок, эреже катары, дал келүүлөрдү табуу үчүн башка жол колдонулат - Matcher классын колдонуу.

 

Матч класс

Matcher классынын негизги ыкмаларын карап көрөлү:

 

  • boolean matches(): эгер бүт сап үлгүгө дал келсе, чындыкты кайтарат

 

  • логикалык find(): эгер сапта үлгүгө дал келген субсап бар болсо жана ошол подсапка секирип өтсө, чындыкты кайтарат

 

  • String group(): издөө ыкмасын чакыруунун натыйжасында үлгүгө дал келген субсапты кайтарат. Эгерде дал келүү жок болсо, анда ыкма IllegalStateException ыргытат.

 

  • int start(): учурдагы дал келүүнүн индексин кайтарат

 

  • int end(): учурдагыдан кийинки дал келүүнүн индексин кайтарат

 

  • String replaceAll(String str): бардык табылган дал келүүлөрдү str ички сап менен алмаштырат жана алмаштырууларды эске алуу менен өзгөртүлгөн сапты кайтарат

 

Биз Matcher классын колдонобуз. Бул үчүн, адегенде, үлгү орнотууга мүмкүндүк берген compile() статикалык ыкмасын колдонуу менен Pattern объектин түзүшүңүз керек:

Pattern pattern = Pattern.compile("Hello");

"Салам" сабы шаблон катары колдонулат. compile() методу Pattern объектисин кайтарат, биз аны программада колдоно алабыз.

 

Pattern классы ошондой эле параметр катары издөө үчүн сапты алып, Matcher объектисин кайтарып берүүчү дал келүүчү(String input) ыкмасын аныктайт:

String input = "Hello world! Hello Java!";

Pattern pattern = Pattern.compile("hello");

Matcher matcher = pattern.matcher(input);

Андан кийин matches() методу тексттеги дал келүүлөрдү табуу үчүн Matcher объектисинде чакырылат:

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

public class StringsApp {

 

    public static void main(String[] args) {

        

        String input = "Hello";

        Pattern pattern = Pattern.compile("Hello");

        Matcher matcher = pattern.matcher(input);

        boolean found = matcher.matches();

        if(found)

            System.out.println("Найдено");

        else

            System.out.println("Не найдено");

    }  

}

Келгиле, сапта толук дал келүүнү эмес, жеке дал келүүлөрдү табуу менен көбүрөөк функционалдык мисалды карап көрөлү:

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

public class StringsApp {

 

    public static void main(String[] args) {

        

        String input = "Hello Java! Hello JavaScript! JavaSE 8.";

        Pattern pattern = Pattern.compile("Java(\\w*)");

        Matcher matcher = pattern.matcher(input);

        while(matcher.find())

            System.out.println(matcher.group());

    }  

}

Келгиле, биз сапта Java сөзүнүн бардык көрүнүштөрүн тапкыбыз келет дейли. Булак сабында бул үч сөз: "Java", "JavaScript" жана "JavaSE". Бул үчүн, "Java(\\w*)" үлгүсүн колдонуңуз. Бул үлгү кадимки туюнтма синтаксисин колдонот. Башындагы "Java" сөзү саптагы бардык дал келүүлөр Java менен башталышы керек экенин көрсөтүп турат. (\\w*) туюнтмасы дал келүүдө "Javaдан" кийин каалаган сандагы тамга-сандык символдор пайда болушу мүмкүн экенин билдирет. \w туюнтмасы алфавиттик-сандык белгини билдирет, ал эми туюнтмадан кийинки жылдызча алардын белгисиз санын көрсөтөт - бир, эки, үч же такыр жок болушу мүмкүн. Жана Java \wду \n сыяктуу качуу ырааттуулугу катары карабашы үчүн, туюнтма башка сызык менен кутулуп кетет.

Matcher классынын find() ыкмасы андан кийин саптагы кийинки дал келүү үчүн чабыттоо үчүн колдонулат. Башкача айтканда, бул ыкмага биринчи чакыруу саптагы биринчи дал келүүнү табат, экинчи чалуу экинчи дал келүүнү табат жана башкалар. Башкача айтканда, while(matcher.find()) циклин колдонуу менен биз бардык дал келүүлөрдү аралап өтө алабыз. Ар бир дал келүүнү matcher.group() ыкмасы менен ала алабыз. Натыйжада, программа төмөнкү натыйжаларды берет:

Java

JavaScript

JavaSE

Бир сапта алмаштыруу

Эми бардык дал келүүлөрдү replaceAll() ыкмасы менен алмаштыралы:

String input = "Hello Java! Hello JavaScript! JavaSE 8.";

Pattern pattern = Pattern.compile("Java(\\w*)");

Matcher matcher = pattern.matcher(input);

String newStr = matcher.replaceAll("HTML");

System.out.println(newStr); // Hello HTML! Hello HTML! HTML 8.

Ошондой эле String классында ушундай эле аракет менен replaceAll() ыкмасы бар экенин белгилей кетүү керек:

String input = "Hello Java! Hello JavaScript! JavaSE 8.";

String myStr =input.replaceAll("Java(\\w*)", "HTML");

System.out.println(myStr); // Hello HTML! Hello HTML! HTML 8.

Сапты токендерге бөлүү

Pattern классынын String[] split(CharSequence input) ыкмасын колдонуп, сиз сапты белгилүү бир бөлгүчтүн негизинде ички саптардын массивине бөлсөңүз болот. Мисалы, биз саптан айрым сөздөрдү чыгаргыбыз келет:

import java.util.regex.Pattern;

 

public class StringsApp {

 

    public static void main(String[] args) {

        

        String input = "Hello Java! Hello JavaScript! JavaSE 8.";

        Pattern pattern = Pattern.compile("[ ,.!?]");

        String[] words = pattern.split(input);

        for(String word:words)

            System.out.println(word);

    }  

}

Ал эми консол бир катар сөздөрдү чыгарат:

Hello

Java

 

Hello

JavaScript

 

JavaSE

8

Бул бардык бөлүүчү белгилерди жок кылат. Бирок, бөлүүнүн бул жолу идеалдуу эмес: бизде чектөөчү катары эмес, белги катары каралган кээ бир боштуктар калды. Так жана татаал бөлүү үчүн биз туруктуу сөз айкаштарынын элементтерин колдонушубуз керек. Ошентип, шаблонду төмөнкүгө алмаштыралы:

 

Pattern pattern = Pattern.compile("\\s*(\\s|,|!|\\.)\\s*");

Эми бизде бир гана сөз калды:

Hello

Java

Hello

JavaScript

JavaSE

8

Андан кийин, биз туруктуу сөз айкаштарынын синтаксисин жана кандай элементтерден үлгү түзө аларыбызды тереңирээк карап чыгабыз.