Reguliariosios išraiškos ir šablonai

 

PERL kalbos pirminė paskirtis buvo palengvinti ir išplėsti ataskaitų kūrimo galimybes UNIX operacinėje sistemoje, todėl natūralu, kad ši kalba turi gerai išvystytas tekstų apdorojimo funkcijas. UNIX operacinėje sistemoje tekstinės informacijos apdorojimui paprastai naudojamos tokios komandas kaip sed, awk, grep, cut. Šių komandų paskirtis yra ribota, todėl norint gauti sudėtingą ataskaitą, rašomi pakankamai dideli ir sudėtingi shell script'ai. Taigi čia į pagalbą ateina PERL kalbos reguliarios išraiškos bei šablonai.

Reguliariosios išraiškos – tai taisyklių rinkiniai, aprašantys tekstinį šabloną, pagal kurį randamas reikalingas tekstas ar fragmentas. Papraščiausios reguliariosios išraiškos – tai literalų eilutės. Sudėtingesnėse reguliariose išraiškose naudojami metasimboliai, kurie apibrėžia galimus ieškomo teksto ar fragmento variantus.

Pačias paprasčiausias reguliariasias išraiškas sudaro vienas paprastas simbolis. Paprastas simbolis reguliarioje išraiškoje reiškia pats save ir papildomai neinterpretuojamas.

Metasimboliai – tai spec.simboliai, turintys tam tikrą reikšmę reguliariose išraiškose. Metasimboliai gali būti naudojami vietoj vieno simbolio arba jų grupės.

Simboliai bei metasimboliai, priklausantys reguliariajai išraiškai, atskiriami  / /  ir formuoja eilutės paieškos šabloną. Pavyzdžiui:

/Perl/  -  atitinka visos eilutės, kuriose yra žodis Perl
            /ab*c/ -  atitinka visos eilutės, kuriose yra simboliai abc (b simbolių gali būti bet koks skaičius)

 Jei šabloną atitinka tekstas eilutėje, tuomet grąžinama reikšmė "true" arba "1", priešingu atveju grąžinama reikšmė "false" arba "0".


PERL metasimboliai ir jų prasmė

Toliau panagrinėsime reguliariose išraiškose naudojamus pagrindinius metasimbolius.

Metasimbolis Reikšmė Pavyzdžiai

\

Metasimbolio maskavimas. Naudojant  "\" , metasimbolis interpre-tuojamas kaip paprastas simbolis, t.y. jam nesuteikiama speciali reikšmė.  "\*" interpretuojamas, kaip *
. Atitinka bet kokį simbolį, išskyrus naujos eilutės simbolį, nors nau-dojant su raktu s , įtraukiamas ir naujos eilutės simbolis.  /Per./
| Skiria alternatyvas, panašiai kaip loginė operacija “arba”.  /a|b|c/
() Grupavimo metasimboliai. Jie paprastai naudojami apibrėžiant kartojimą (žr.žemiau).  /And(y|rew)/  - bus ieškoma Andy arba Andrew
[] Nurodo, kad šablone naudojamas vienas iš simbolių esančių skliaustuose. [A-Za-z] – bet kuri abėcėlės raidė; [^0-9] – bet kuris simbolis, išskyrus skaičių.
"^" laužtiniuose skliaustuose reiškia neigimą.
\t Tabuliacija (HT, TAB)  
\n nauja eilutė (LF, NL)  
\r "karietėlės" grąžinimas (CR)  
\f puslapio prasukimas (FF)  
\a "Skambutis"  
\e Escape  
\033 Simbolis su nurodyta reikšme (aštuntainėje sistemoje)  
\x1B Simbolis su nurodyta reikšme (šešioliktainėje sistemoje)  
\c[ Control-simbolis  
\l nurodo, kad sekanti raidė turi būti mažoji  
\u nurodo, kad sekanti raidė turi būti didžioji  
\L nurodo, kad tolesnės raidės nuo \L iki \E turi būti mažosios  
\U nurodo, kad tolesnės raidės nuo \U iki \E turi būti mažosios  
\E keitimo pabaiga  
\Q cituoti metasimbolius iki \E literaliai  
\w Žodis ar simbolis (raidės, skaičiai ir "_" ženklas). \w iš esmės tas pats kaip [a-zA-Z_0-9]  
\W neŽodis ar nežodžiams naudojamas simbolis.
\W
tas pats kaip [^a-zA-Z_0-9]
 
\s Tuščia vieta (tarpas, tabuliacija). \s tas pats kaip [\t\n\r\f]  
\S Netuščia vieta. \S tas pats kaip [^\t\n\r\f]  
\d Skaitmuo t.y. tas pats kaip [0-9]  
\D Ne skaitmuo t.y. tas pats kaip [^0-9]  
\0 simbolis, turinti kodą 0  
\skaičius grupavimo konstrukcijos t.y. skliaustų “( )” numeris reguliarioje išraiškoje (numeruojama nuo 1) /fred(.)barney\1/ - atitinka  fredXbarneyX   /a(.)b(.)c\2d\1/ - atitinka axbycydx

 

Vietą nurodantys metasimboliai

Žemiau išvardinti simboliai nurodo ieškomo teksto vietą eilutėje. Dažniausiai naudojami ^ ir $ metsimboliai reiškiantys atitinkamai eilutės pradžią ir pabaigą.

Metasimbolis Reikšmė Pavyzdžiai
^ Eilutės pradžią reiškiantis metasimbolis  
$ Eilutės pabaigą reiškiantis metasimbolis, jei jis randasi šablono pa-baigoje. Kitoje vietoje esantis metasimbolis nurodo, kad į šabloną reikia įterpti kintamojo reikšmę.  
\b Žodžio riba (vieta, kur prasideda arba baigiasi žodis)  
\B ne žodžio riba (visos vietos, išskyrus tas, kur prasideda arba baigiasi žodis)  
\A Eilutės pradžia  
\Z Eilutės pabaiga arba vieta prieš naują eilutę  
\z Tik eilutės pabaiga  
\G Vieta, kur baigė prieš tai veikusi m//g komanda  

 

Pasikartojimo nurodymas reguliariose išraiškose

Žemiau išvardinti simboliai pasako, kad prieš juos buvusi reguliarioji išraiška (t.y. iš kairės) gali pasikartoti eilutėje tam tikrą kiekį kartų.

 

Metasimbolis Reikšmė Pavyzdžiai
*   kartoti 0 ir daugiau kartų  /.*/ - bet kuri eilutė
+   kartoti 1 ir daugiau kartų  /.+/ - bet kuri netuščia eilutė
?   kartoti 0 arba 1 kartą  /(array)?/ - žodis array bus 1 arba 2 kartus eilutėje
{n}   kartoti tiksliai n kartų  /[0-9]{3}/ - bet koks tri-ženklis skaičius
{n,}   kartoti n ir daugiau kartų  /r{5,}/
{n,m}   kartoti nuo n iki m kartų  /r{2,5}/

 



Kintamieji, susiję su reguliariomis išraiškomis

 Jei eilutėje buvo rastas tekstas, atitinkantis šabloną, tai likusi eilutės dalis, neatitikusi šablono, yra priskiriama specialiems kintamiesiems. Šabloną atitikęs tekstas taip pat priskiriamas specialiajam kintamajam.
 

Metasimbolis Reikšmė
$& Eilutės dalis, atitikusi šabloną
$` Eilutės dalis, likusi prieš šabloną atitikusią eilutės dalį
$' eilutės dalis, likusi už šabloną atitikusios eilutės dalies

 

Pavyzdys

$_ = "tai yra testinis pavyzdys";
/tes.*nis/;     # atitinka žodį "testinis"
                # $`   reikšmė "tai yra "
                # $&   reikšmė "testinis"
                # $'   reikšmė "pavyzdys"

 

Jei reguliarioje išraiškoje naudojamas grupavimas, tai radus eilutėje tekstą, kuris atitiko šabloną, sukuriami kintamieji $1, $2, $3 ir t.t., kurie turi tas pačias reikšmes kaip ir \1, \2, \3 ir t. t. Pavyzdžiui:

$_ = "this is a test";
/(\w+)\W+(\w+)/; # šį šabloną atitinka pirmi du žodžiai, todėl
                 # $1 dabar yra "this", o $2 turi reikšmę "is"



Išplėstinės reguliariosios išraiškos

Norint išplėsti šablonų panaudojimo galimybes, buvo praplėsta reguliariųjų išraiškų sintaksė įvedant (?.....) konstrukciją. Simbolis, einantis po “?”, apibrėžia funkciją, kuri turi būti atliekama. Šiuo metu naudojama apie dešimt išplėstinių reguliariųjų išraiškų konstrukcijų. Panagrinėkime dažniausiai naudojamas konstrukcijas.

 
(?#text)         tekstas esantis po "#"  ir iki  " )"  laikomas komentaru ir ignoruojamas. Pavyzdžiui
                        /Perl(?# ieškome žodžio Perl)/.

(?:pattern)  grupavimas, kaip ir "(...)" atveju, tačiau nesukuriami kintamieji $1, $2 ir t. t. (žr. aukščiau). Pavyzdžiui /(?:Perl|perl)/.

(?=pattern)  sekantis teksto fragmentas turi atitikti pattern. Tai reiškia, kad prieš šią konstrukciją turi būti šablonas, o tik po jo (?=pattern). Pavyzdžiui, /\w+(?=\t)/ atitinka žodį, po kurio iš kart eina tabuliacija. Be to tabuliacija nepriskiriama $& kintamajam.

(?!pattern) ši konstrukcija reiškia, jog sekantis teksto fragmentas neturi atitikti pattern. Pavyzdžiui, /foot(?!ball)/ atitinka bet kurį žodį ar jo fragmentą “foot”, išskyrus “football”. “ball” nepriskiriamas $& kintamajam.

(?<=pattern) konstrukcija reiškianti, jog prieš buvęs teksto fragmentas turi atitikti pattern. Pavyzdžiui, /(?<=bad)boy/ atitinka žodį “boy”, jei prieš jį buvo “bad”. Be to “bad” nepriskiriamas $& kintamajam.

(?<!=pattern) konstrukcija reiškianti, jog prieš buvęs teksto fragmentas neturi atitikti pattern. Pavyzdžiui, /(?<!=bad)boy/ atitinka bet kurį žodį “boy”, jei prieš jį nebuvo “bad”. “bad” nepriskiriamas $& kintamajam.

(?>pattern)  atitinka eilutę, kurioje pattern yra nurodytoje pozicijoje.

 

Naudojant išplėstines reguliariasias išraiškas, galima naudoti ir paiešką modifikuojančius raktus t.y. (?imsx-imsx). Jie dar vadinami modifikatoriais. Jei prieš raides i, m, s, x rašomas “-“, tuomet modifikatorius atšaukiamas. Pavyzdžiui /(?ix) perl # ignoruojamos didž.-maž. raidės ir bei galimi tarpai šablone/
Žemiau pateikti modifikatorių paaiškinimai. 
 

Modifikatorius Reikšmė
i Paieška ignoruojant didžiasias ir mažasias raides.
m Eilutė traktuojama kaip multi-eilutė, kurią sudaro keletas eilučių atskirtų naujos eilutės simboliu.
s Eilutė traktuojama kaip viena eilutė. Metasimbolis “.” reiškia bet kokį simbolį, tame tarpe ir naujos eilutės simbolį.
x Leidžiama šablonuose naudoti komentarus ir tarpo simbolius.

 


 

Veiksmai naudojant reguliariasias išraiškas

Išsiaiškinę reguliariųjų išraiškų formavimo principus, pereikime prie sekančio etapo, t. y. reguliariųjų išraiškų panaudojimo Perl skriptuose. Taigi reguliariosios išraiškos paprastai naudojamos norint atlikti paieškos operaciją, pakeitimo ar transliteracijos veiksmus. Panagrinėkime kiekvieną iš šių operacijų.

 
PAIEŠKA

 Sintakė

     m/pattern/[g i m o s x]

Paieškos operacija atlieka šabloną atitinkančio teksto paiešką. Operacijos rezultatas gali būti reikšmė 1 (”true”) arba tuščia eilutė (“false”). Pagal nutylėjimą paieška vykdoma eiltutėje,  priskirtoje specialiajam kintamajam $_. Naudojant pririšimo operatorius “=~” ir “!~” galima atlikti paiešką ir kitiems kintamiesiems priskirtose eilutėse. Operatoriai “=~” ir “!~” skiriasi tuo, kad grąžina skirtingas logines reikšmes. Pavyzdžiui:

$var = “Mano batai buvo du”;
$var =~ m/^Man./;                 #vykdome paiešką kintamajam $var priskirtoje eilut
ėje
                                  #ir gražinama true, nes randamas žodis Mano
$var !~ m/^Man./                  #false, nes randamas žodis Mano

 

Raktai  g i m o s x  modifikuoja paieškos operacijas. Žemiau pateiktas jų aprašymas.
 

Raktai Reikšmė
g Globali paieška t.y. bus rasti visi teksto fragmentai eilutėje, atitinkantys paieškos šabloną. Pagal nutylėjimą paieška baigiama suradus pirmąjį atitikmenį.
i Paieška ignoruojant didžiasias ir mažasias raides
m Eilutė traktuojama kaip multi-eilutė, kurią sudaro keletas eilučių atskirtų naujos eilutės simboliu
o Kintamieji, esantys šablone, naudojami tik vieną kartą.
s Eilutė traktuojama kaip viena eilutė. Metasimbolis “.” reiškia bet kokį simbolį, tame tarpe ir naujos eilutės simbolį
x Leidžiama šablonuose naudoti komentarus ir tarpo simbolius.

Pavyzdžiai

#Ignoruojamos didžiosios bei mažosios raidės
print "Ar pratesti darbą? ";
if (<STDIN> =~ m/^y]/i) {                # tikrinama ar įvedimas pradedamas y simboliu?
    print "Tai šaunu\n! ";
}

#Globali paieška masyvo ir skaliariniame kontekste
$str="abaabbaaabbb";
@result = $str =~ m/a+b+/g;               #masyvo kontekstas globalioje paieškoje
print "\@result = @result\n";
@result = $str =~ m/(a+)(b+)/g;           #masyvo kontekstas globalioje paieškoje
print "\@result = @result\n";
print "Skaliarinis kontekstas\n";
while ($result=$str =~m/ m/(a+)(b+)/g; {  #skaliarinis kontekstas globalioje paieškoje
    print "result=$result \n";
}

#Paieška naudojant skirtingus raktus
@pattnlist = ("a+", "b+", "c+", "d+");    #masyvas, apibrėžiantis paieškas
foreach $pattn (@pattnlist) {
   $line = <STDIN>;
$line =~ m/$pattn/o                       #dėl rakto o, naudojamas tik a+
šablonas
    print "pattn=$pattn \$& = $&\n";
}

 

PAKEITIMAS

Sintakė

     s/pattern/replacement/[e g i m o s x]

Pakeitimo operacija s/pattern/replacement/ atlieka šabloną pattern atitinkančio teksto paiešką ir, jei jis randamas, pakeičiamas tekstu replacement. Operacijos grąžinama reikšmė – atliktų pakeitimų skaičius arba tuščia eilutė, jei nebuvo atliktas nei vienas pakeitimas. Pagal nutylėjimą paieška vykdoma eiltutėje, priskirtoje specialiajam kintamajam $_ . Naudojant pririšimo operatorius “=~” ir “!~” galima atlikti paiešką ir kitiems kintamiesiems priskirtose eilutėse, pavyzdžiui:

   $var =~ s/pattern/replacement/[e g i m o s x]

Raktai  g i m o s x  reiškia tą patį kaip ir atliekant paieškos operaciją, o raktas e pasako, kad keičiamąjį tekstą replacement pirmiausiai reikia interpretuoti kaip PERL išraišką, o tik po to atlikti pakeitimus.

Pavyzdžiai

$_= "foot fool buffoon";
s/foo/bar/g;                         #dabar $_  yra
"bart barl bufbarn"
 

$_= "this is a test";
s/(w+)/<$1>/g;      
                 # dabar  $_  yra "<this>  <is>  <a >  <test>"
 

$_= "Hello world";
$new =
"Goodbye";
s/hello/$new/;         
             # dabar  $_  yra "Goodbye world"
 

$str = "abaabbaaabbb";
$result=$str =~s[(a+b+)]<length($1)>ge;
print
"result=$result new str=$str\n";       #result=3 new str=246
 

TRANSLITERACIJA

 Sintakė

     tr/searchlist/replacement/[c d s]

Transliteracijos operacija keičia kiekvieną simbolį iš sąrašo searchlist į atitinkamą simbolį iš pakeitimų sąrašo replacement. Pagal nutylėjimą pakeitimai atliekami eiltutėje, priskirtoje specialiajam kintamajam $_ . Naudojant pririšimo operatorius “=~” ir “!~” galima atlikti paiešką ir kitiems kintamiesiems priskirtose eilutėse, pavyzdžiui:

     $var =~ tr/searchlist/replacement/[c d s]

Simbolių sąrašai searchlist ir replacement gali būti pateikiami kaip atskirai išvardinti simboliai ar simbolių diapazonai. Pavyzdžiui:

    $str =~ tr/A-Z/a-z/      #didžiosios raidės keičiamos mažosiomis.

Žemiau pateiktas raktų, naudojamų transliteracijos operacijose, aprašymas.

 

Raktai Reikšmė
c Paieškos sąrašas searchlist praplėčiamas per visą ASCII lentelę
d Naikinami visi simboliai iš sarašo searchlist, kurie neturi atitinkamo elemento replacement sąraše.
s Visi simboliai, kurie buvo pakeisti į vienodą simbolį, keičiami vieninteliu jo egzemplioriumi.


Pavyzdžiai

$count = $str =~ tr/\000/ /c      #suskaičiuojamas simbolių skaičius eilutėje.

$str =~ tr/\200-\377/ /cs         #bet kuri simbolių seka nuo ASCII kodo 128 iki 255
                                  #keičiama vieninteliu tarpo simboliu

$_ = "fred and barney";
tr/fb/bf/;                        # $_ dabar "bred and farney"
tr/abcde/ABCDE/;                  # $_ dabar "BrED AnD fArnEy"
tr/a-z/A-Z/;                      # $_ dabar "BRED AND FARNEY"
$count = tr/A-Z//;                # $_ nepakeistas, o $count lygus 13
$count1 = tr/A-Z//c;              # $_ nepakeistas, o $count1 lygus 2 (suskaičiuoti
                                  #    neraidiniai simboliai t.y. tarpai)
tr/A-Z/x/;                        # $_ dabar "xxxx xxx xxxxxx"
tr/a-z/_/c;                       # $_ dabar "xxxx_xxx_xxxxxx" t.y. (non-letters => _)
 



Naudingos eilučių apdorojimo funkcijos

 

Žemiau pateikiamos dažniausiai naudojamos PERL funkcijos, skirtos darbui su eilutėmis.

 

Funkcija Sintaksė Reikšmė
chop() chop($str) Pašalina eilutės paskutinį simbolį. Funkcija grąžina pašalintą simbolį.
lenght() lenght(str) Grąžinamas eilutės str ilgis.
lc() lc(expression) Gražinama eilutė mažosiomis raidėmis
uc() uc(expression) Gražinama eilutė didžiosiomis raidėmis
lcfirst() lcfirst(expression) Pirmas eilutės simbolis keičiamas į mažąją raidę
ucfirst() ucfirst(expression) Pirmas eilutės simbolis keičiamas į didžiąją raidę
split() split([/pattern/[,expr[,limit]]] Pagal šabloną sudalina eilutę į laukus
join() join(expression,list) Sujungia laukus (masyvo narius) į vieną eilutę.
index() index(str,substr[,position]) Eilutėje str ieškoma eilutė substr nuo  pozicijos position bei grąžinama rasta pozicija. Jei substr nerasta - gražinama f-jos reikšmė -1
rindex() rindex(str,substr[,position]) Eilutėje str ieškoma eilutė substr iki  pozicijos position bei grąžinama rasta pozicija. Jei substr nerasta - gražinama f-jos reikšmė -1
substr() substr(str,offset[,lenght[,repl]]) Iš eilutės str paimama lenght ilgio subeilutė, esanti į dešinę nuo offset pozicijos. Jei užduotas parametras repl, tai subeilutė keičiama į repl.
eval() eval{expression} Funkcija parametrą expression vykdo, kaip PERL programinį kodą. Jei expression nenurodytas, naudojamas kintamasis $_. Jei įvyko klaida, kintamajame $@ talpinamas klaidos pranešimas.

Pavyzdžiai

 

#Pozicijos paieška eilutėje
$person = "barney";
$where = index("fred barney",$person);       # $where lygus 5
$where = index("hello world","l");           # $where lygus 2 (pirmasis l)
$where = index("hello world","l",3);         # $where lygus 3

$w = rindex("hello world","he");             # $w lygus 0
$w = rindex("hello world","l");              # $w lygus 9 (dešiniausias l eilutėje)
$w = rindex("hello world","xx");             # $w lygus -1 (nes nerastas)
 

#Eilutės dalies paėmimas arba pekeitimas
$hello = "hello, world!";
$grab  = substr($hello, 3, 2);               # $grab lygus "lo"
$grab  = substr($hello, 7, 100);             # $grab lygus "world!"
substr($hello, 0, 5) = "hi";                 # $hello dabar "hi world!"

#Vykdoma PERL kodas, nuskaitytas iš STDIN
print "code line: ";
chop($code = <STDIN>);
eval $code; die "eval: $@" if $@;                # PERL kodas vykdomas, jei nėra klaidų

#Eilutės skaidymas ir sujungimas
$line = "merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl";
@fields = split(/:/,$line);                      # skaidoma $line, ties rastais :
#
# dabar @fields yra ("merlyn","","118","10","Randal","/home/merlyn","/usr/bin/perl")
#
$outline = join(":", @fields);    #atstatoma  eilutė $line naujame kintamajame $outline

 


Į turinį