JavaRush /Java блогу /Random-KY /Javaдагы кадимки туюнтмалар (RegEx)

Javaдагы кадимки туюнтмалар (RegEx)

Группада жарыяланган
Регулярдуу сөз айкаштары программисттер, атүгүл тажрыйбалуулар да, көбүнчө кийинчерээк калтыра турган тема. Бирок, көпчүлүк Java иштеп чыгуучулары эртеби-кечпи текстти иштетүү менен күрөшүүгө туура келет. Көбүнчө - текстте издөө операциялары жана түзөтүү менен. Регулярдуу туюнтмаларсыз, текстти иштетүү менен байланышкан жемиштүү жана компакт программалык codeду элестетүү мүмкүн эмес. Андыктан аны кийинкиге калтырганды токтоткула, келгиле, азыртан эле “регулярлар” менен алек бололу. Бул анчалык кыйын иш эмес.

RegEx кадимки туюнтмасы деген эмне?

Чындыгында, кадимки туюнтма (Javaдагы RegEx) текстте сапты издөө үчүн үлгү болуп саналат. Javaда бул үлгүнүн баштапкы көрүнүшү дайыма сап болуп саналат, башкача айтканда, String классынын an objectиси. Бирок, эч кандай сапты регулярдуу туюнтмага түзүүгө болбойт, регулярдуу туюнтманы жазуу эрежелерин сактагандарды гана - тил спецификациясында аныкталган синтаксис. Туруктуу сөз айкашын жазуу үчүн алфавиттик жана сандык символдор, ошондой эле метасимволдор - туруктуу сөз айкаштарынын синтаксисинде өзгөчө мааниге ээ болгон символдор колдонулат. Мисалы:
String regex = "java"; // string template "java";
String regex = "\\d{3}"; // string template of three numeric characters;

Javaда кадимки туюнтмаларды түзүү

Java ичинде RegEx түзүү үчүн, сиз эки жөнөкөй кадамдарды аткарышыңыз керек:
  1. аны кадимки туюнтма синтаксисин колдонуп сап катары жазуу;
  2. бул сапты регулярдуу туюнтмага түзүңүз;
Ар кандай Java программасында кадимки туюнтмалар менен иштөө класс an objectин түзүү менен башталат Pattern. Бул үчүн, класста жеткorктүү эки статикалык методдун бирин чакырышыңыз керек compile. Биринчи ыкма бир аргументти алат - регулярдуу туюнтумдун сап литералы, экинчиси - шаблон менен текстти салыштыруу режимин иштеткен дагы бир параметр:
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
Мүмкүн болгон параметр баалуулуктарынын тизмесиflags класста аныкталган Patternжана биз үчүн статикалык класс өзгөрмөлөрү катары жеткorктүү. Мисалы:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//searching for matches with the pattern will be done case-insensitively.
Негизи класс Patternкадимки туюнтма конструктору. Капоттун астында метод компиляцияланган көрүнүштү түзүү үчүн compileкласстын жеке конструкторун чакырат . PatternКалыптын инстанциясын түзүүнүн бул ыкмасы аны өзгөрүлгүс an object катары түзүү максатында ишке ашырылат. Түзүүдө кадимки сөз айкашынын синтаксиси текшерилет. Эгерде сапта каталар болсо, өзгөчө жагдай түзүлөт PatternSyntaxException.

Регулярдуу туюнтма синтаксиси

<([{\^-=$!|]})?*+.>Регулярдуу туюнтма синтаксиси алфавиттик символдор менен айкалыштырыла турган символдорду колдонууга негизделген . Алардын ролуна жараша, алар бир нече топко бөлүүгө болот:
1. Сызыктын чектерин же текстти дал келүү үчүн мета символдор
Метабелги Максат
^ саптын башталышы
$ саптын аягы
\b сөздүн чеги
сөз менен чектелбейт
киргизүүнүн башталышы
мурунку матчтын аягы
киргизүүнүн аягы
\z киргизүүнүн аягы
2. Каарман класстарын издөө үчүн метакаармандар
Метабелги Максат
\d санариптик символ
сандык эмес белги
\s космостук мүнөз
бош эмес белги
\w алфавиттик-сандык белги же астын сызуу
\ В алфавиттик, сандык же астын сызыктан башка каалаган белги
. кандайдыр бир каарман
3. Текстти түзөтүү символдорун издөө үчүн мета символдор
Метабелги Максат
өтмөк белгиси
\n жаңы сап белгиси
\r каретка кайтаруу мүнөзү
\f жаңы баракка өтүү
\u0085 кийинки сап белгиси
\u 2028 сызык бөлүүчү белги
\u 2029 абзац бөлүүчү символ
4. Персонаждарды топтоо үчүн мета символдор
Метабелги Максат
[a B C] жогорудагылардын кайсынысы (a, b, же c)
[^abc] тизмеленгендерден башкасы (a, b, c эмес)
[a-zA-Z] диапазонду бириктирүү (латын тамгалары aдан zге чейинки тамгаларды сезбейт)
[ad[mp]] символдордун бириктирorши (a-d жана м-дан p)
[az&&[def] символдордун кесorши (d,e,f символдору)
[az&&[^bc]] белгилерди кемитүү (а, dz символдору)
5. Символдордун санын көрсөтүүчү метасимволдор - кванторлор. Сандык көрсөткүч ар дайым белгиден же символдор тобунан кийин келет.
Метабелги Максат
? бир же жок
* нөл же андан көп жолу
+ бир же бир нече жолу
{n} n жолу
{n,} n жолу же андан көп
{n,m} n эседен кем эмес жана м эседен көп эмес

Ач көздүк кванттоочу режим

Кванторлордун өзгөчөлүгү аларды түрдүү режимдерде колдонуу мүмкүнчүлүгү болуп саналат: ач көз, өтө ач көз жана жалкоо. Кошумча ач көздүк режими+ квантордон кийин “ ” белгисин, ал эми жалкоо режими “ “ белгисин кошуу менен күйгүзүлөт ?. Мисалы:
"A.+a" // greedy mode
"A.++a" // over-greedy mode
"A.+?a" // lazy mode
Мисал катары бул шаблонду колдонуу менен, келгиле, кванторлор ар кандай режимдерде кантип иштээрин түшүнүүгө аракет кылалы. Демейки боюнча, квантор ач көз режимде иштейт. Бул сапта мүмкүн болушунча узун дал келүүнү издейт дегенди билдирет. Бул codeду иштетүүнүн натыйжасында:
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()));
    }
}
биз төмөнкү натыйжаны алабыз: Alla Alexa Берилген үлгү боюнча издөө алгоритми " А.+а" төмөнкү ырааттуулукта аткарылат:
  1. Берилген үлгүдө биринчи символ орус тамгасынын белгиси А. Matcherаны нөл позициясынан баштап тексттин ар бир белгисине дал келтирет. Биздин тексттин нөл позициясында символ бар Е, ошондуктан Matcherал үлгү менен дал келгенге чейин тексттеги символдор аркылуу ырааттуу өтөт. Биздин мисалда бул №5 позициядагы символ.

    Java тorндеги кадимки туюнтмалар - 2
  2. Үлгүнүн биринчи символу менен дал келгендик табылгандан кийин, Matcherал оюмдун экинчи белгисине дал келгенин текшерет. Биздин учурда, бул .кандайдыр бир белгини билдирген “ ” белгиси.

    Java тorндеги кадимки туюнтмалар - 3

    Алтынчы орунда тамга белгиси турат л. Албетте, ал "ар кандай каармандын" үлгүсүнө дал келет.

  3. Matcherүлгүдөгү кийинки белгини текшерүүгө өтөт. Биздин шаблондо ал “ .+” кванторунун жардамы менен көрсөтүлгөн. Үлгүдөгү "кандайдыр бир белгинин" кайталануу саны бир же бир нече жолу болгондуктан, Matcherал кезек менен саптан кийинки символду алып, "кандай болбосун символ" шарты аткарылса, анын үлгүгө ылайык келүүсүн текшерет. биздин мисалда - саптын аягына чейин (тексттин No 7 - No 18 позициясынан).

    Java тorндеги кадимки туюнтмалар - 4

    Чынында, Matcherал бүт линияны аягына чейин басып алат - бул жерде анын "ач көздүгү" көрүнөт.

  4. MatcherТексттин аягына жетип, үлгүнүн “ ” бөлүгүн текшерип бүткөндөн кийин А.+, Матчер үлгүнүн калган бөлүгүн - тамга белгисин текшере баштайт а. Алдыга багытталган текст аяктагандыктан, текшерүү акыркы белгиден баштап тескери багытта жүргүзүлөт:

    Java тorндеги кадимки туюнтмалар - 5
  5. MatcherТексттин аягына жеткен " " үлгүсүндөгү кайталоолордун санын .+"эсинде сактайт", ошондуктан кайталоолордун санын бирге азайтат жана дал келгенче тексттин үлгүсүн текшерет: Java тorндеги кадимки туюнтмалар - 6

Ультра ачкөз сандык көрсөткүч режими

Супер ачкөз режимде дал келүүчү ачкөз режиминин механизмине окшош иштейт. Айырмачылыгы, текстти саптын аягына чейин кармаганда, артка издөө болбойт. Башкача айтканда, супер ачкөз режиминдеги алгачкы үч этап ач көздүк режимине окшош болот. Бүтүндөй жипти тартып алгандан кийин, дал келүүчү үлгүнүн калган бөлүгүн кошуп, аны алынган жип менен салыштырат. Биздин мисалда " А.++а" үлгүсү менен негизги ыкманы аткарууда эч кандай дал келүү табылbyte. Java тorндеги кадимки туюнтмалар - 7

Жалкоо кванттоочу режим

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

    Java тorндеги кадимки туюнтмалар - 8
  2. Андан кийин, ал үлгүдөгү кийинки белгиге дал келүүнү издейт - каалаган белги:

    Java тorндеги кадимки туюнтмалар - 9
  3. Ач көз режимден айырмаланып, жалкоо режим тексттеги эң кыска дал келүүнү издейт, ошондуктан чекит менен көрсөтүлгөн үлгүнүн экинчи символу менен дал келүүнү тапкандан кийин тексттин No6 позициясындагы символго дал келет, ал Matcherтекст үлгүнүн калган бөлүгүнө дал келгенин текшерет - “ а” белгиси.

    Java тorндеги кадимки туюнтмалар - 10
  4. Тексттеги оюм-чийим менен дал келүү табылбагандыктан (тексттин №7 позициясында “ “ белгиси бар л), Matcherал бир же бир нече жолу көрсөтүлгөндүктөн, оюмга дагы бир “каалаган белгини” кошот, жана дагы үлгүнү №5тен 8ге чейинки позициялардагы текст менен салыштырат:

    Java тorндеги кадимки туюнтмалар - 11
  5. Биздин учурда дал келүү табылды, бирок тексттин аягына чыга элек. Демек, №9 позициядан текшерүү окшош алгоритмди колдонуу менен үлгүнүн биринчи символун издөө менен башталат жана тексттин аягына чейин кайталанат.

    Java тorндеги кадимки туюнтмалар - 12
Методдун натыйжасында main" " шаблонун колдонууда А.+?атөмөнкү натыйжага ээ болобуз: Алла Alexa Биздин мисалдан көрүнүп тургандай, бир эле шаблон үчүн ар кандай кванттоочу режимдерди колдонгондо, биз ар кандай жыйынтыктарды алдык. Ошондуктан, бул өзгөчөлүктү эске алуу жана издөө учурунда каалаган натыйжага жараша керектүү режимди тандоо керек.

Туруктуу сөз айкаштарындагы качуучу символдор

Java тorндеги регулярдуу туюнтма же тагыраак айтканда анын баштапкы көрүнүшү сап литералы аркылуу көрсөтүлгөндүктөн, сап литералдарына тиешелүү Java спецификациясынын эрежелерин эске алуу зарыл. Атап айтканда, \Java булак codeундагы сап литералдарындагы артка сызык белгиси " " качуу символу катары чечмеленет, ал компиляторго андан кийинки символ өзгөчө белги экенин жана өзгөчө жол менен чечмелениши керек экенин эскертет. Мисалы:
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
Ошондуктан, регулярдуу туюнтманы сүрөттөгөн жана " \" символун колдонгон сап литералдарында (мисалы, метасимволдор үчүн) Java byte-code компилятору аны башкача чечмелөө үчүн эки эсеге көбөйтүлүшү керек . Мисалы:
String regex = "\\s"; // template for searching for space characters
String regex = "\"Windows\""; // pattern to search for the string "Windows"
Эгерде биз аларды "кадимки" символдор катары колдонууну пландаштырсак, атайын символдордон качуу үчүн кош сызык белгиси да колдонулушу керек. Мисалы:
String regex = "How\\?"; // template for searching the string "How?"

Pattern классынын методдору

Класста Patternрегулярдуу туюнтмалар менен иштөө үчүн башка ыкмалар бар: String pattern()– an object түзүлгөн регулярдуу сөз айкашынын баштапкы сап көрүнүшүн кайтарат Pattern:
Pattern pattern = Pattern.compile("abc");
System.out.println(Pattern.pattern())//"abc"
static boolean matches(String regex, CharSequence input)– regex параметринде берилген регулярдуу туюнтманы параметрде өткөн текстке салыштырып текшерүүгө мүмкүндүк берет input. Кайтарйт: true – текст үлгүгө дал келсе; жалган - башкача; Мисал:
System.out.println(Pattern.matches("A.+a","Alla"));//true
System.out.println(Pattern.matches("A.+a","Egor Alla Alexander"));//false
int flags()flagsкалыптын түзүлгөндө коюлган параметр маанилерин кайтарат, же бул параметр коюлбаган болсо 0. Мисал:
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)– параметр катары берилген текстти элементтер массивине бөлөт String. Параметр limitтекстте изделген дал келүүлөрдүн максималдуу санын аныктайт:
  • качан limit>0– дал келүүлөрдү издөө limit-1жүргүзүлөт;
  • at limit<0– тексттеги бардык дал келүүлөрдү издейт
  • качан limit=0– тексттеги бардык дал келүүлөрдү издейт, ал эми массивдин аягындагы бош саптар жокко чыгарылат;
Мисал:
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);
    }
}
Консолдун чыгышы: Егор Алла Анна -------- Егор Алла АннаMatcher Төмөндө an objectти түзүүнүн дагы бир класстык ыкмасын карап чыгабыз.

Матч классынын методдору

Matcherүлгүлөрдү издөө үчүн an object түзүлгөн класс болуп саналат. Matcher– бул “издөө системасы”, туруктуу сөз айкаштарынын “мотору”. Издөө үчүн ага эки нерсе берorши керек: издөө үлгүсү жана издөө үчүн "дареги". Объектти түзүү үчүн Matcherкласста төмөнкү ыкма каралган Pattern: рublic Matcher matcher(CharSequence input) Аргумент катары метод издөө аткарыла турган символдордун ырааттуулугун алат. Булар интерфейсти ишке ашырган класстардын an objectилери CharSequence. StringЖалаң эле эмес , StringBuffer, StringBuilderжана аргумент катары Segmentда өтсө болот CharBuffer. Издөө үлгүсү - Patternбул метод чакырылган класс an objectи 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"
Эми биздин “издөө системабыздын” жардамы менен биз дал келүүчүлөрдү издеп, тексттеги дал келүүнүн ордун бorп, класстык методдорду колдонуу менен текстти алмаштыра алабыз. Метод boolean find()үлгү менен тексттин кийинки дал келүүсүн издейт. Бул ыкманы жана цикл операторун колдонуп, окуянын модели боюнча бүткүл текстти талдай аласыз (окуя болгондо керектүү операцияларды аткарыңыз - тексттен дал келүүнү табуу). Мисалы, бул класстын ыкмаларын колдонуу менен тексттеги дал келүүлөрдүн ордун аныктай аласыз, ал эми методдорду колдонуп int start(), тексттеги дал келүүчүлөрдү башка алмаштыруучу текст менен алмаштырсаңыз болот. Мисал: 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);
}
Программанын натыйжасы: Ширеңке табылды Алла 5тен 8 позицияга чейин Ширеңке табылды Анна 10дон 13кө чейин Егор Ира Анна Егор Ольга Ольга Егор Алла Анна Мисалдан көрүнүп тургандай, ыкмалар жаңы an objectти - сапты replaceFirstжаратат . шаблон менен дал келүүлөр аргумент катары методго берилген текст менен алмаштырылган баштапкы текст. Мындан тышкары, ыкма биринчи матчты гана алмаштырат, ал эми тесттеги бардык дал келүүчүлөр. Түпнуска текст өзгөрүүсүз бойдон калууда. Башка класстык ыкмаларды колдонуу , ошондой эле туруктуу сөз айкаштарынын мисалдарын ушул макалалар сериясынан тапса болот . Текст менен иштөөдө туруктуу сөз айкаштары менен эң кеңири таралган операциялар класстардан алынган жана . Бул , , , сыяктуу ыкмалар . Бирок, чындыгында, "капоттун астында" алар жана . Ошондуктан, эгер сизге керексиз code жазбастан эле программадагы текстти алмаштыруу же саптарды салыштыруу керек болсо, . Эгер сизге өркүндөтүлгөн мүмкүнчүлүктөр керек болсо, класстар жана . replaceAllStringreplaceFirstreplaceAllMatcherPatternMatcherStringsplitmatchesreplaceFirstreplaceAllPatternMatcherStringPatternMatcher

Корутунду

Кадимки сөз айкашы Java программасында эрежелер менен аныкталган үлгүгө дал келген саптарды колдонуу менен сүрөттөлөт. Код иштегенде, Java бул сапты класс an objectине кайра компиляциялайт жана тексттеги дал келүүлөрдү табуу үчүн Patternкласс an objectисин колдонот . MatcherБашында айткандай, туруктуу сөз айкаштары көбүнчө кийинчерээк четте калып, оор тема катары каралат. Бирок, эгер сиз синтаксистин негиздерин түшүнсөңүз, метабелгилер, качуу жана туруктуу сөз айкаштарынын мисалдарын изилдеп көрсөңүз, алар биринчи караганда көрүнгөндөн алда канча жөнөкөй болуп чыгат.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION