Основе регуларних израза у Ц ++

Regular Expression Basics C



Размотрите следећу реченицу под наводницима:

'Ево мог човека.'

Овај низ се можда налази унутар рачунара и корисник ће можда желети да зна има ли реч ман. Ако има реч мушкарац, можда ће хтети да промени реч мушкарац у жена; тако да низ треба да гласи:







'Ево моје жене.'

Постоје многе друге жеље попут корисника рачунара; неки су сложени. Регуларни израз, скраћено регек, предмет је решавања ових проблема помоћу рачунара. Ц ++ долази са библиотеком која се зове регек. Дакле, Ц ++ програм за руковање регуларним изразом треба да почне са:



#инцлуде

#инцлуде

користећи именски простор стд;

Овај чланак објашњава основе регуларног израза у Ц ++.



Садржај чланка

Основе регуларног израза

Регек

Жица попут Хере ис ми ман. горе је циљна секвенца или циљни низ или једноставно, циљ. ман, за којим се трагало, регуларни је израз или једноставно регекс.





Подударање

Подударање се јавља када се реч или израз који се тражи налази. Након подударања, може доћи до замене. На пример, након што се мушкарац налази изнад, може га заменити жена.

Једноставно подударање

Следећи програм приказује како се подудара реч човек.



#инцлуде

#инцлуде

користећи именски простор стд;

интглавни()
{

регек рег('човек');
ако (регек_сеарцх('Ево мог човека.',рег))
цена<< 'упарен' <<ендл;
елсе
цена<< 'не подудара се' <<ендл;

повратак 0;
}

Функција регек_сеарцх () враћа труе ако постоји подударање и враћа фалсе ако нема подударања. Овде функција узима два аргумента: први је циљни низ, а други је регек објекат. Сам регекс је 'човек', у двоструким наводницима. Први израз у функцији маин () формира регек објект. Регек је тип, а рег је регек објекат. Излаз горњег програма се 'подудара', јер се 'ман' види у циљном низу. Да 'ман' није виђен у циљу, регек_сеарцх () би вратио фалсе, а излаз би био 'нот матцх'.

Излаз следећег кода се не подудара:

регек рег('човек');
ако (регек_сеарцх('Ево мог стварања.',рег))
цена<< 'упарен' <<ендл;
елсе
цена<< 'не подудара се' <<ендл;

Не подудара се јер регек 'ман' није могао да се нађе у целом циљном низу, 'Хере ис ми макинг.'

Шаблон

Регуларни израз, човек горе, је врло једноставан. Регекси обично нису тако једноставни. Регуларни изрази имају метакарактере. Метазнакови су ликови са посебним значењем. Метакарактер је лик о ликовима. Ц ++ регуларни изрази метакарактери су:

^$ .* + ? ( ) [ ] { } |

Регуларни израз, са или без метазнакова, је образац.

Класе ликова

Угласте заграде

Узорак може имати знакове унутар углатих заграда. Са овим, одређена позиција у циљном низу би се подударала са било којим од знакова углатих заграда. Узмите у обзир следеће циљеве:

'Мачка је у соби.'

'Шишмиш је у соби.'

'Пацов је у соби.'

Регуларни израз, [цбр] ат би одговарао мачки у првој мети. То би одговарало палици у другој мети. Одговарао би пацову у трећој мети. То је зато што мачка, шишмиш или пацов почињу са „ц“ или „б“ или „р“. Следећи сегмент кода то илуструје:

регек рег('[цбр] у');
ако (регек_сеарцх('Мачка је у соби.',рег))
цена<< 'упарен' <<ендл;
ако (регек_сеарцх('Шишмиш је у соби.',рег))
цена<< 'упарен' <<ендл;
ако (регек_сеарцх('Пацов је у соби.',рег))
цена<< 'упарен' <<ендл;

Излаз је:

упарен

упарен

упарен

Распон ликова

Класа, [цбр] у обрасцу [цбр], одговарала би неколико могућих знакова у циљу. То би одговарало „ц“ или „б“ или „р“ у мети. Ако на мети нема „ц“ или „б“ или „р“, иза које следи ат, не би било подударања.

Неке могућности попут „ц“ или „б“ или „р“ постоје у распону. Опсег цифара од 0 до 9 има 10 могућности, а образац за то је [0-9]. Распон малих слова, а до з, има 26 могућности, а образац за то је [а-з]. Распон великих слова, од А до З, има 26 могућности, а образац за то је [А-З]. - званично није метакарактер, али би у угластим заградама означио опсег. Дакле, следеће производи подударање:

ако (регек_сеарцх('ИД6ид',регек('[0-9]')))

цена<< 'упарен' <<ендл;

Обратите пажњу на то како је регекс конструисан као други аргумент. Подударање се дешава између цифре 6 у опсегу, 0 до 9 и 6 у циљу, ИД6ид. Горњи код је еквивалентан:

ако (регек_сеарцх('ИД6ид',регек('[0123456789]')))

цена<< 'упарен' <<ендл;

Следећи код производи подударање:

цхарп[] = 'ИД6иЕ';

ако (регек_сеарцх(п,регек('[а-з]')))

цена<< 'упарен' <<ендл;

Имајте на уму да је први аргумент овде стринг променљива, а не литерал низала. Подударање је између 'и' у [а-з] и 'и' у ИД6иЕ.

Не заборавите да је распон класа. Може бити текст десно од опсега или лево од опсега у обрасцу. Следећи код производи подударање:

ако (регек_сеарцх('ИД2ид је лична карта ',регек('ИД [0-9] ид')))

цена<< 'упарен' <<ендл;

Подударање је између ИД [0-9] ид и ИД2ид. Остатак циљног низа је ИД, у овој ситуацији се не подудара.

Као што се користи у субјекту регуларног израза (регекс), реч класа заправо значи скуп. То јест, један од ликова у сету треба да се подудара.

Напомена: Цртица - је метакарактер само у угластим заградама, што означава опсег. То није метакарактер у регуларном изразу, изван угластих заграда.

Негација

Класа која укључује опсег може се негирати. То јест, ниједан од знакова у скупу (класи) не би требало да се подудара. Ово је означено метакарактором ^ на почетку узорка класе, одмах након углате заграде. Дакле, [^0-9] значи подударање карактера на одговарајућој позицији у мети, што није било који знак у распону, укључујући 0 до 9. Дакле, следећи код неће произвести подударање:

ако (регек_сеарцх('0123456789101112',регек('[^ 0-9]')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Цифра унутар опсега од 0 до 9 се може наћи на било којој од циљних позиција низа, 0123456789101112 ,; па нема подударања - негације.

Следећи код производи подударање:

ако (регек_сеарцх('АБЦДЕФГХИЈ',регек('[^ 0-9]')))

цена<< 'упарен' <<ендл;

Ниједна цифра није пронађена у мети, АБЦДЕФГХИЈ ,; па постоји подударање.

[а-з] је опсег изван [^а-з]. И тако је [^а-з] негација [а-з].

[А-З] је опсег изван [^А-З]. И тако је [^А-З] негација [А-З].

Постоје и друге негације.

Матцхинг Вхитеспацес

‘’ Или т или р или н или ф је знак размака. У следећем коду, регуларни израз, н се подудара са „ н“ у циљу:

ако (регек_сеарцх('Први ред. р нРед два. ',регек(' н')))

цена<< 'упарен' <<ендл;

Подударање било ког празног карактера

Узорак или класа која одговарају било ком знаку размака је, [ т р н ф]. У следећем коду, '' се подудара:

ако (регек_сеарцх('један два',регек('[ т р н ф] ')))

цена<< 'упарен' <<ендл;

Подударање са било којим знаком који није размак

Узорак или класа која одговарају било ком знаку који није размак је: [^ т р н ф]. Следећи код производи подударање јер нема празних места у циљу:

ако (регек_сеарцх('1234абцд',регек('[^ т р н ф] ')))

цена<< 'упарен' <<ендл;

Тачка (.) У обрасцу

Тачка (.) У узорку одговара било ком знаку, укључујући и њега самог, осим н, у циљу. Подударање се производи у следећем коду:

ако (регек_сеарцх('1234абцд',регек('.')))

цена<< 'упарен' <<ендл;

У следећем коду нема резултата који се подударају јер је циљ н.

ако (регек_сеарцх(' н',регек('.')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Напомена: Унутар класе знакова са угластим заградама тачка нема посебно значење.

Подударање понављања

Знак или група знакова може се појавити више пута унутар циљног низа. Узорак може одговарати овом понављању. Метазнакови,?, *, +И {} се користе за подударање понављања у циљу. Ако је к интересантни знак у циљном низу, онда метазнакови имају следеће значење:

Икс*:значи утакмица'Икс' 0или више пута,и.И.,било који број пута

Икс+:значи утакмица'Икс' 1или више пута,и.И.,најмање једном

Икс? :значи утакмица'Икс' 0или1 време

Икс{н,}:значи утакмица'Икс'најмање н или више пута.Белешказарез.

Икс{н} :утакмица'Икс'тачно н пута

Икс{н,м}:утакмица'Икс'најмање н пута,али не више од м пута.

Ови метакарактери се зову квантификаторе.

Илустрације

*

* Одговара претходном знаку или претходној групи, нула или више пута. о* подудара се са „о“ у пасу циљног низа. Такође се подудара са оо у књизи и изгледу. Редовни израз, о* се подудара са боооо у Животиња бооооед .. Напомена: о* се подудара са копањем, где се „о“ појављује нула (или више) времена.

+

Знак + одговара претходном знаку или претходној групи, 1 или више пута. Упоредите то са нулом или више пута за *. Дакле, регуларни израз, е+ се подудара са „е“ у јелу, где се „е“ појављује једном. е+ се такође подудара са ее код оваца, где се „е“ јавља више пута. Напомена: е+ неће одговарати диг -у јер се у диг -у 'е' не појављује бар једном.

?

Тхе? одговара претходном знаку или претходној групи, 0 или 1 пут (и не више). Дакле, е? подудара се са дигом јер се „е“ појављује у копању, нула времена. е? подудара се јер се „е“ појављује у скупу, једном. Напомена: е? још увек одговара овцама; иако у овцама постоје два „е“. Овде постоји једна нијанса - погледајте касније.

{н,}

Ово одговара најмање н узастопних понављања претходног карактера или претходне групе. Дакле, регуларни израз, е {2,} одговара два „е“ у мети, овце, и три „е“ у циљном овцу. е {2,} се не подудара са скупом, јер скуп има само једно „е“.

{н}

Ово одговара тачно н узастопних понављања претходног карактера или претходне групе. Дакле, регуларни израз, е {2} се подудара са два „е“ у циљу, овце. е {2} се не подудара са скупом јер скуп има само једно „е“. Па, е {2} се подудара са два „е“ у мети, овче. Овде постоји једна нијанса - погледајте касније.

{н, м}

Ово се подудара са неколико узастопних понављања претходног карактера или претходне групе, било где од н до м, укључујући ово. Дакле, е {1,3} се ништа не подудара у диг -у, који нема 'е'. Одговара једном 'е' у сету, два 'е' у овцама, три 'е' у овцама и три 'е' у овцама. На последњој утакмици постоји једна нијанса - погледајте касније.

Матцхинг Алтернатион

Размислите о следећем циљном низу на рачунару.

На фарми се налазе свиње различитих величина.

Програмер ће можда желети да зна да ли ова мета има козу, зеца или свињу. Код би био следећи:

цхарп[] = 'Фарма има свиње различитих величина.';

ако (регек_сеарцх(п,регек('коза | зец | свиња')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Код производи подударање. Обратите пажњу на употребу алтернативног знака, |. Могу постојати две, три, четири и више опција. Ц ++ ће прво покушати да усклади прву алтернативу, козју, на свакој позицији карактера у циљном низу. Ако не успе са козом, покушава следећу алтернативу, зец. Ако не успе са зецом, покушава следећу алтернативу, свињу. Ако свиња не успе, онда Ц ++ прелази на следећу позицију у мети и поново почиње са првом алтернативом.

У горњем коду свиња се подудара.

Подударање почетка или краја

Почетак


Ако је ^ на почетку регуларног израза, тада се регуларни израз може подударати са почетним текстом циљног низа. У следећем коду почетак циља је абц, који се подудара:

ако (регек_сеарцх('абц и деф',регек('^ абц')))

цена<< 'упарен' <<ендл;

Нема подударања у следећем коду:

ако (регек_сеарцх('Да, абц и деф',регек('^ абц')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Овде абц није на почетку мете.

Напомена: Циркумфлексни знак, ‘^’, је метакарактер на почетку регуларног израза, који одговара почетку циљног низа. Још увек је метакарактер на почетку класе карактера, где негира класу.

Крај

Ако је $ на крају регуларног израза, тада се регуларни израз може упоредити са завршним текстом циљног низа. У следећем коду крај циља је киз, који се подудара:

ако (регек_сеарцх('увв и киз',регек('киз $')))

цена<< 'упарен' <<ендл;

Нема подударања у следећем коду:

ако (регек_сеарцх('увв и киз финал',регек('киз $')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Овде киз није на крају мете.

Груписање

Заграде се могу користити за груписање знакова у шаблону. Размислите о следећем регуларном изразу:

'концерт (пијаниста)'

Овде је група пијаниста окружена метакарактерима (и). То је заправо подгрупа, док је концерт (пијаниста) цела група. Узмите у обзир следеће:

'(Пијаниста је добар)'

Овде, подгрупа или подниз је, пијаниста је добар.

Подниз са заједничким деловима

Књиговођа је особа која се брине о књигама. Замислите библиотеку са књиговођом и полицом за књиге. Претпоставимо да се један од следећих циљних низова налази у рачунару:

'Библиотека има полицу са књигама које се диве.';

'Овде је књиговођа.';

'Књиговођа ради са полицом за књиге.';

Претпоставимо да интерес програмера није да зна која се од ових реченица налази у рачунару. Ипак, његов интерес је да зна да ли је полица за књиге или књиговођа присутна у било ком циљном низу у рачунару. У овом случају његов регекс може бити:

'полица за књиге | књиговођа.'

Користећи алтернацију.

Запазите да је књига, која је заједничка за обе речи, откуцана два пута, у две речи у обрасцу. Да бисте избегли два пута куцање књиге, регекс би било боље написати као:

'књига (полица | чувар)'

Овде, група, полица | Менаџер наизменичења се још увек користио, али не за две дугачке речи. Коришћен је за два завршна дела две дугачке речи. Ц ++ третира групу као ентитет. Дакле, Ц ++ ће тражити полицу или чувара који долази одмах након књиге. Излаз следећег кода се подудара:

цхарп[] = 'Библиотека има полицу са књигама које се диве.';

ако (регек_сеарцх(п,регек('књига (полица | чувар)')))

цена<< 'упарен' <<ендл;

полице за књиге, а не књиговођа су упарене.

Ицасе и мултилине регек_цонстантс

ицасе

Подударање подразумевано разликује велика и мала слова. Међутим, може се учинити неосетљивим на велика и мала слова. Да бисте то постигли, користите регек :: ицасе константу, као у следећем коду:

ако (регек_сеарцх('Повратна информација',регек('напајање',регек::ицасе)))

цена<< 'упарен' <<ендл;

Излаз је усклађен. Дакле, повратне информације са великим словима „Ф“ су усклађене са феедом са малим словима „ф“. регек :: ицасе је постао други аргумент конструктора регек (). Без тога, изјава не би дала подударност.

Мултилине

Узмите у обзир следећи код:

цхарп[] = 'Линија 1 нред 2 нлинија 3 ';

ако (регек_сеарцх(п,регек('^. * $')))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Излаз се не подудара. Регуларни израз, ^.*$, Одговара циљном низу од његовог почетка до краја. .* значи било који знак осим н, нула или више пута. Дакле, због знакова новог реда ( н) у циљу, није било подударања.

Циљ је вишередни низ. Да би се „.“ Подударало са знаком новог реда, мора се направити константан регек :: мултилине, други аргумент конструкције регек (). Следећи код то илуструје:

цхарп[] = 'Линија 1 нред 2 нлинија 3 ';

ако (регек_сеарцх(п,регек('^. * $',регек::мултилине)))

цена<< 'упарен' <<ендл;

елсе

цена<< 'не подудара се' <<ендл;

Подударање целог низа мета

За подударање са целим циљним низом, који нема знак новог реда ( н), може се користити функција регек_матцх (). Ова функција се разликује од регек_сеарцх (). Следећи код то илуструје:

цхарп[] = 'прва друга трећина';

ако (регек_матцх(п,регек('.*сецонд.*')))

цена<< 'упарен' <<ендл;

Овде има подударања. Међутим, имајте на уму да се регуларни израз подудара са целим циљним низом, а циљни низ нема никакав знак н.

Објекат матцх_ресултс

Регек_сеарцх () функција може узети аргумент између циља и регек објекта. Овај аргумент је објект матцх_ресултс. Цео подударни (део) низ и подударани поднизови могу бити познати са њим. Овај објекат је посебан низ са методама. Тип објекта матцх_ресултс је цматцх (за литералне знакове).

Добијање утакмица

Узмите у обзир следећи код:

цхарп[] = 'Жена коју сте тражили!';

цматцх м;

ако (регек_сеарцх(п,м,регек('в.м.н')))

цена<<м[0] <<ендл;

Циљни низ има реч жена. Излаз је жена ', што одговара регуларном изразу, в.м.н. Код нула индекса, специјални низ садржи једино подударање, а то је жена.

Са опцијама класе, само први подниз који се налази у циљу, шаље се у посебан низ. Следећи код то илуструје:

цматцх м;

ако (регек_сеарцх('Пацов, мачка, шишмиш!',м,регек('[бцр] у')))

цена<<м[0] <<ендл;

цена<<м[1] <<ендл;

цена<<м[2] <<ендл;

Излаз је пацов из индекса нула. м [1] и м [2] су празни.

Са алтернативама, само први подниз који се налази у циљу, шаље се у посебан низ. Следећи код то илуструје:

ако (регек_сеарцх('Зец, коза, свиња!',м,регек('коза | зец | свиња')))

цена<<м[0] <<ендл;

цена<<м[1] <<ендл;

цена<<м[2] <<ендл;

Излаз је зец из индекса нула. м [1] и м [2] су празни.

Груписања

Када су групе укључене, комплетан образац се подудара и иде у нулу ћелије специјалног низа. Следећи пронађени подниз долази у ћелију 1; подниз који следи, иде у ћелију 2; и тако даље. Следећи код то илуструје:

ако (регек_сеарцх(„Најбољи продавац књига данас!“,м,регек('боок ((сел) (лер))')))

цена<<м[0] <<ендл;

цена<<м[1] <<ендл;

цена<<м[2] <<ендл;

цена<<м[3] <<ендл;

Излаз је:

књижар

продавац

мобилни

читати

Имајте на уму да група (продавац) долази испред групе (сел).

Позиција утакмице

Позиција подударања за сваки подниз у низу цматцх може бити позната. Одбројавање почиње од првог знака циљног низа, на позицији нула. Следећи код то илуструје:

цматцх м;

ако (регек_сеарцх(„Најбољи продавац књига данас!“,м,регек('боок ((сел) (лер))')))

цена<<м[0] << '->' <<м.положај(0) <<ендл;

цена<<м[1] << '->' <<м.положај(1) <<ендл;

цена<<м[2] << '->' <<м.положај(2) <<ендл;

цена<<м[3] << '->' <<м.положај(3) <<ендл;

Запазите употребу својства позиције са индексом ћелије као аргумент. Излаз је:

књижар->5

продавац->9

мобилни->9

читати->12

Тражи и замени

Нова реч или израз могу заменити подударање. За то се користи функција регек_реплаце (). Међутим, овог пута, низ где долази до замене је стринг објекат, а не литерал низа. Дакле, библиотека стрингова мора бити укључена у програм. Илустрација:

#инцлуде

#инцлуде

#инцлуде

користећи именски простор стд;

интглавни()
{
стринг стр= 'Ево, долази мој човјек. Ево твог човјека. ';
стринг невСтр=регек_реплаце(п,регек('човек'), 'жена');
цена<<невСтр<<ендл;

повратак 0;
}

Функција регек_реплаце (), како је овде кодирана, замењује сва подударања. Први аргумент функције је таргет, други је регек објект, а трећи је замјенски низ. Функција враћа нови низ, који је циљ, али има замену. Излаз је:

Ево долази моја жена. Ево твоје жене.

Закључак

Регуларни израз користи обрасце за подударање поднизова у низу циљног низа. Обрасци имају метакарактере. Уобичајено коришћене функције за регуларне изразе Ц ++ су: регек_сеарцх (), регек_матцх () и регек_реплаце (). Редовни израз је образац у двоструким наводницима. Међутим, ове функције узимају регек објект као аргумент, а не само регек. Регек мора бити претворен у регек објект да би га ове функције могле користити.