Sunteți pe pagina 1din 25

Universitatea Tehnic a Republicii Moldovei

Facultatea de Calculatoare, Informatic i Microelectronic


Catedra Informatic Aplicat

Lucrare de Curs
La disciplina: Programarea bazat pe reguli i expresii regulare
Tema: Proiectarea i elaborarea unui program Perl

A efectuat

st.gr IA-131M Pivovarcic Serghei

A verificat:

conf.univ Liviu Carcea

Chiinu 2014

Cuprins
ntroducere n PERL........................................................................................................................3
Caracteristici ale limbajului.........................................................................................................3
Un prim program.........................................................................................................................3
Expresii regulate n Perl..............................................................................................................6
Pattern matching..........................................................................................................................7
Substitutia si traducerea...............................................................................................................8
Split............................................................................................................................................13
Un argument n plus n favoarea Perl........................................................................................13
Referine n perl.............................................................................................................................14
Crearea referinelor:...................................................................................................................14
Dereferencing............................................................................................................................15
Referine circulare.....................................................................................................................16

ntroducere n PERL
Perl este un limbaj simplu de nvatat si utilizat, dar care ofera mecanisme puternice si
eficiente. Este un limbaj cu ajutorul caruia orice programator si poate rezolva problemele din
domeniul profesional, evident. Este un limbaj care stimuleaza creativitatea programatorului prin
libertatea de exprimare pe care o ofera.
Articolul de fata si propune o prezentare sumara a ctorva din caracteristicile si facilitatile
oferite de Perl, fiind doar o introducere modesta n mecanismele de prelucrare ale limbajului.
Scopul principal este de a va face cunoscut ca acest limbaj exista si ca poate fi utilizat eficient
pentru implementarea diferitelor aplicatii software. Articolul contine totodata si o scurta
descriere a expresiilor regulate care constituie cheia instrumentelor de prelucrare a textelor n
Perl.

Caracteristici ale limbajului


Dintre caracteristicile importante ale limbajului Perl [2, 5] putem aminti:
- Modularitatea - limbajul permite proiectarea, programarea si depanarea rapida a
aplicatiilor, dar si extinderea functionalitatii acestor aplicatii conform cerintelor care se ivesc;
Perl poate fi ncorporat n aplicatiile din alte limbaje de programare, precum poate ncorpora la
rndul sau cod scris n alte limbaje.
- Viteza de dezvoltare a programelor - n Perl programele se pot scrie folosind orice editor
de texte; nu este necesar un compilator separat; ciclul compileaza-executa-modifica este mult
mai scurt.
- Puterea limbajului - asa cum s-a precizat anterior, Perl ofera unul dintre cele mai
puternice mecanisme de lucru cu expresii regulate; ofera facilitati pentru lucrul cu obiecte si
socketi, baze de date, etc.
- Portabilitatea - programele scrise n Perl pot fi executate fara nici o modificare att n
sistemele de operare UNIX, ct si n orice versiune de Windows sau alt sistem de operare.
- Mediul de dezvoltare - orice editor de texte este suficient pentru dezvoltarea de aplicatii
Perl; programele pot fi scrise n joe, vi sau Notepad, Word 97.
- Pretul - ntr-adevar Perl este ... nepretuit; poate fi procurat si utilizat liber.

Un prim program
Traditia ar spune ca un prim program sa constea n afisarea mesajului "Hello World!", nsa
experienta spune ca un program mai interesant, care sa scoata n evidenta simplitatea si totodata
puterea limbajului Perl, ar strni repede si definitiv interesul cititorilor.
Enuntul unui prim program este de asemenea foarte simplu. Rezultatele unui examen sunt
stocate ntr-un fisier. Examenul are trei probe: scris, oral si proba practica. n fisier apar doua
coloane: prima contine numele studentului, iar a doua coloana, nota obtinuta la una din cele trei
probe. Cele doua coloane sunt despartite de ":". Numele unui student poate apare de mai multe
ori n fisier, n functie de cte probe a sustinut. Cerinta problemei este de a afisa pentru fiecare
student numele si nota finala. Studentii vor fi afisati n ordinea descrescatoare a notei finale.
(vezi Listing 1)

Dupa cum se poate lesne observa, programul este usor de nteles, n special pentru
programatorii de C sau shell. Numerele de la nceputul fiecarei linii nu au nici o legatura cu
programul, fiind nsa utile pentru comentarea acestuia. Deci nu folositi aceste numere la scrierea
programelor n Perl!
Fiecare program scris n Perl ncepe cu linia:
#!/usr/local/bin/perl
care poate diferi n functie de calea n care se afla executabilul limbajului Perl. Aceasta
linie specifica faptul ca fisierul trebuie executat ca un program Perl.
Linia numarul 5 din program ncearca sa deschida fisierul care contine datele de intrare
pentru citire. Aceasta linie se compune de fapt din doua instructiuni legate printr-un sau logic: or.
n cazul n care fisierul de intrare este deschis pentru citire, cea de a doua instructiune nu se mai
executa. n caz contrar, se executa cea de-a doua instructiune care se termina ntotdeauna cu
succes, n sensul ca, executia programului este oprita, afisndu-se mesajul indicat mpreuna cu
tipul erorii stocat ntr-una din variabilele speciale ale Perl-ului: $!.
Trebuie mentionat ca, limbajul Perl dispune de o serie ntreaga de variabile speciale care la
prima vedere ar conduce la o ntelegere mai dificila a programelor, dar care de fapt ajuta foarte
mult programatorii la reducerea dimensiunii programelor si la cresterea eficientei acestora.
Liniile 7-13 contin instructiunile necesare pentru citirea linie cu linie a datelor din fisier si
stocarea lor ntr-o tabela hash. O tabela hash este un sir ale carui elemente sunt accesate dupa
chei si nu dupa numere sau dupa un index ca la sirurile obisnuite. n cazul de fata, numele
studentilor reprezinta cheile tabelei, iar notele reprezinta valorile sale. Notele sunt memorate
toate ntr-un singur string, fiind despartite de cte un spatiu. Deci notele asociate fiecarui student
pot fi accesate utiliznd cheia studentului, adica numele sau.
Fisierul de intrare este nchis (n linia numarul 15) o data ce toate datele de intrare au fost
memorate n tabela hash.
Parcurgerea unei tabele hash se poate face dupa cheile sau valorile sale. Linia numarul 17
indica modul n care se parcurge tabela dupa chei, adica dupa numele studentilor.
Pentru a calcula nota finala a fiecarui student, trebuie calculata media notelor obtinute la
probele sustinute. Deoarece notele studentilor sunt memorate ntr-un string, se face conversia
stringului la un sir, n care fiecare element al sirului reprezinta o nota (linia numarul 21). Linia
numarul 21 reprezinta oarecum operatia inversa celei de la numarul 12.
Pentru afisarea rezultatelor trebuie facuta ordonarea descrescatoare a studentilor n functie
de nota finala. Aceasta operatie este realizata de continutul parantezei rotunde din linia 35.
Functia sort primeste doi parametrii: o functie dupa care se face sortarea si un sir care trebuie
sortat. sirul specificat ca parametru n linia 35 reprezinta de fapt un sir format din numele
studentilor.
Liniile 30-33 contin definitia subrutinei, care poate fi considerata o functie sau o
procedura, ce compara doua elemente ntorcnd un ntreg, adica rezultatul functiei cmp. Nu sunt
direct comparate valorile $a si $b deoarece acestea reprezinta doua elemente ale sirului ce trebuie
sortat, adica doua nume de studenti, si nu notele lor, pe cnd cerinta problemei este de a ordona

studentii n functie de notele obtinute. n Perl nu se face distinctie ntre functii si proceduri,
existnd doar subrutine.
Pentru a executa acest program n UNIX, trebuie ca fisierul n care este stocat sa aiba
drepturi de executie. Programul se poate executa prin simpla comanda:
perl [optiuni] nume_program lista_argumente
Optiunile sunt utilizate pentru obtinerea de informatii suplimentare n timpul
compilarii/interpretarii programului sau pentru specificarea modului n care se doreste efectuarea
compilarii/interpretarii sau executiei programului (de exemplu, optiunea -c verifica
corectitudinea programului din punct de vedere sintactic, fara a-l executa).
Ca si n C sau Java, se pot specifica argumentele transmise programului n linia de
comanda prin lista_argumente.
Daca programul contine erori, acestea pot fi sau nu afisate pe ecran. Pentru a vizualiza
mesajele de eroare, de atentionare sau orice alt tip de mesaj util pentru nlaturarea erorilor, se
foloseste optiunea "-w":
perl -w nume_program
sau se adauga la prima linie de program:
#!/usr/local/bin/perl -w
Pentru a rula programul pentru depanare, se utilizeaza optiunea "-d". Toate celelalte optiuni
pot fi descoperite prin comanda man perlrun.
Cnd este lansata comanda pentru executia programului, Perl compileaza mai nti tot
programul dupa care executa versiunea compilata.
Comentariile pot fi introduse oriunde n program. Orice comentariu ncepe cu caracterul
"#" (exceptnd prima linie din program) si se termina la sfarsitul liniei care contine "#". O alta
modalitate de introducere a comentariilor n programe este utilizarea unei linii care ncepe cu
semnul egal urmat imediat de o litera. Sfrsitul comentariului este indicat de semnul egal urmat
de cuvntul "cut", aflate la inceputul unei linii urmatoare. Tot ceea ce se afla ntre cele doua linii
care ncep cu semnul egal, este considerat comentariu.
=Comentariu!
Acesta este un exemplu de comentariu n Perl!
=cut
care este echivalent cu :
#Comentariu!
#Acesta este un exemplu de comentariu n Perl!
Atentie: Perl este case sensitive, adica $var si $Var reprezinta doua variabile diferite.

Trei observatii
- O observatie importanta este aceea ca programul prezentat n listing 1 nu contine nici o
declaratie de tip. Toate variabilele sunt folosite direct, fara a fi nevoie sa fie declarate anterior. n
schimb, fiecare variabila este precedata de unul din caracterele $, @, %, care indica implicit tipul
variabilelor, adica scalar, sir si respectiv, tabele hash sau array-uri asociative. Acest lucru permite
citirea si ntelegerea usoara a programului, nefiind necesara defilarea ntregului program pentru a
gasi locul de declaratie a variabilei respective si a-i afla tipul.
- n Perl nu exista notiunea de cast, adica conversia explicita de tip. Conversia de tip se
face automat (de exemplu, conversia numerelor n stringuri). Un exemplu care sustine afirmatia
anterioara este linia numarul 11 din programul prezentat. Elementele unui sir sunt stocate ntr-un
string, fiind despartite de cte un spatiu. Daca sirul are doua elemente:
$nume_student[0] este "Ion"
$nume_student[1] este "Ionescu"
atunci
$nume_final este "Ion Ionescu"
n cazul n care s-ar renunta la "" si instructiunea ar deveni:
$nume_final = @nume_student;
rezultatul ar fi cu totul altul (n variabila scalara $nume_final s-ar memora lungimea arrayului @nume_student). Acest lucru se datoreaza schimbarii de context, pentru ca n Perl totul se
evalueaza n functie de contextul existent.
- Alocarea si dealocare variabilelor este de asemenea facuta n mod automat. Nu este
nevoie de specificarea numarului de elemente ale unui sir si nici de alocarea sau dealocarea
spatiului corespunzator. n C, programatorul trebuie sa aiba grija de alocarea si dealocarea
variabilelor, pe cnd n Java este necesara doar alocarea spatiului corespunzator, deoarece are
implementat mecanismul de garbage collector. nsa Perl rezolva automat ambele probleme. De
exemplu, poate memora ntr-un singur string continutul unui ntreg fisier, daca evident exista
memoria necesara, aspect ce nu tine de limbaj. Speram ca a cstigat deja simpatia multor
programatori prin aceasta caracteristica importanta.

Expresii regulate n Perl


Mecanismele de manipulare a textelor reprezinta una dintre cele mai importante si
puternice facilitati oferite de limbajul Perl, expresiile regulate constituind nucleul acestor
mecanisme. Expresiile regulate sunt folosite n special n programe si aplicatii UNIX: grep, sed,
awk, vi, emacs, si nu numai.
Dar ce este o expresie regulata? O expresie regulata este considerata o gramatica regulata
pentru un limbaj. Interpretorul de expresii regulate compara gramatica cu sirul de caractere n
care se face cautarea. Daca o parte din sirul de cautare poate fi considerat ca fiind o propozitie ce
apartine limbajului, atunci interpretorul va ntoarce ca rezultat valoarea de adevar, altfel valoarea
de fals.

Ceea ce se ntmpla dupa ce interpretorul gaseste o propozitie care satisface expresia


regulata depinde de scopul cautarii expresiei regulate:
- determinarea existentei unui sir de caractere care satisface expresia regulata; n acest caz
rezultatul va fi o valoare booleana: adevarat sau fals; n general aceste expresii regulate apar n
instructiuni conditionale;
- substituirea sirului de caractere care satisface expresia regulata cu un alt string specificat
de programator; n acest caz rezultatul va fi un numar ntreg pozitiv, care reprezinta numarul de
substitutii efectuate;
- divizarea unui sir de caractere dupa expresia regulata; rezultatul va fi reprezentat de o
lista a partilor sirului de cautat care nu satisfac expresia regulata (expresia regulata joaca n acest
caz un rol de delimitator pentru partile din string care nu satisfac expresia regulata).

Pattern matching
Cazul cel mai simplu n care sunt utilizate expresiile regulate este pattern matching, adica
determinarea existentei unui sir de caractere care satisface expresia regulata. Un exemplu de
aplicatie pattern matching este: sa se afiseze toate liniile dintr-un fisier HTML care contin linkuri catre alte pagini HTML. Orice astfel de link care apare ntr-un fisier HTML ncepe cu "http:".
Este suficient sa se parcurga fisierul linie cu linie si sa se verifice existenta stringului "http:" n
fiecare linie:
while ( $linie = <FIS_HTML> )
}
Operatorul =~ se numeste pattern-binding. Este un operator infixat care leaga stringul de
cautare cu expresia regulata de cautat. Expresia regulata este de obicei delimitata de slash-uri. n
cazul n care operatorul =~ nu apare n instructiunea if, fiind specificata doar expresia regulata de
cautat /http:/, Perl considera variabila speciala $_ ca variabila implicita de cautare. $_ este
variabila implicita si pentru <>, operatorul de citire din fisier. Astfel secventa anterioara devine:
while ( <FIS_HTML> )
Daca se doreste afisarea tuturor liniilor din fisierul HTML care contin orice tip de link
atunci secventa corespunzatoare de cod este:
while ( <FIS_HTML> )
Parantezele patrate definesc o clasa de caractere, n acest caz clasa tuturor literelor din
alfabet. Semnul plus are urmatoarea semnificatie: "una sau mai multe aparitii a ceea ce este n
fata mea" (adica una sau mai multe litere pentru exemplul prezentat). Deci, n acest caz, orice tip
de link (http:, hTtP:, mailto:, ftp:, FTP:) este descris de expresia regulata din exemplul anterior.
Exista patru variabile speciale asociate expresiilor regulate: $+, $&, $`, $'.

$+ contine stringul care corespunde utimei paranteze evaluate din expresia regulata
$& contine ntregul string care corespunde expresiei regulate
$` contine tot ceea ce este naintea stringului corespunzator expresiei regulate
$' contine tot ceea ce urmeaza stringului corespunzator expresiei regulate
raibulet@athena.polito.it. Astept mail.';
/(\w+)\@(.*?)\s/;
print "Ultima paranteza evaluata din expresia regulata: $+.\n";
print "Ce este naintea expresiei regulate: $`.\n";
print "Expresia regulata: $&.\n";
print "Ce este dupa expresia regulata: $'.\n";
Variabilele speciale vor avea urmatoarele valori n urma executiei acestei secvente de cod:
$+ : athena.polito.it
$` : Adresa de e-mail este:
$& : raibulet@athena.polito.it.
$' : Astept mail.

Substitutia si traducerea
De cele mai multe ori nu este suficient un rezultat boolean care sa indice existenta sau
inexistenta unei anumite expresii regulate n cadrul unui text sau al unei variabile, dorindu-se
modificarea sau substituirea totala sau partiala a string-ului gasit.
Limbajul Perl ofera doua metode distincte pentru prelucrarea expresiei regulate
identificate:
- substitutia - permite nlocuirea ntregului sir de caractere care satisface expresia regulata
cu un alt sir specificat de programator;
- traducerea - permite nlocuirea partiala sau chiar totala a sirului de caractere care satisface
expresia regulata, substitutia facndu-se caracter cu caracter.
Functia cu ajutorul careia se realizeaza substitutia n Perl se numeste "s". Att expresia
regulata de nlocuit, ct si expresia de nlocuire sunt ncadrate de delimitatori.
$_ = "Piesa de teatru \"Azilul de noapte\" am vazut-o azi la matineu.";
$nr_de_inlocuiri = s/azi/ieri/ig;

print "Numarul de nlocuiri este: $nr_de_inlocuiri.\n";


Functia "s" substituie orice secventa de caractere care satisface expresia de cautat cu ceea
ce se gaseste ntre al doilea si al treilea delimitator (n cazul de fata "ieri"). Numarul de nlocuiri
afisat dupa executia acestei secvente de cod este 2 si nu 1, asa cum ar fi fost de asteptat.
Din punct de vedere semantic, n exemplul de mai sus se dorea schimbarea
complementului de timp, nsa substitutia se face pentru orice aparitie consecutiva a literelor "a",
"z" si "i", indiferent daca ele formeaza un cuvnt separat sau fac parte din cadrul unui cuvnt.
Secventa de cod corecta care satisface cerinta si din punct de vedere semantic este:
$_ = "Piesa de teatru \"Azilul de noapte\" am vazut-o azi la matineu.";
$nr_de_inlocuiri = s/\bazi\b/ieri/ig;
print "Numarul de nlocuiri este: $nr_de_inlocuiri.\n";
"\b" indica nceputul sau sfrsitul unui cuvnt. Rezultatul afisat de aceasta data este 1, iar
ntelesul nou al frazei este cel dorit.
O aplicatie imediata a substitutiei este stergerea stringurilor care satisfac expresia regulata
specificata. Aceasta se realizeaza prin inserarea n cadrul substitutiei a sirului vid ca expresie
regulata de nlocuire:
$_ = "Piesa de teatru \"Azilul de noapte\" am vazut-o azi la matineu.";
$nr_de_inlocuiri = s/\bazi\b//ig;
print "Noul string este: $_ \n";
sirul sau sirurile de caractere care satisfac expresia regulata de cautat pot fi memorate n
cadrul unui scalar sau n cadrul unei liste n functie de scopul urmarit:
$_ = "Piesa de teatru <I>Azilul de noapte</I> am vazut-o ieri la <I>Notara</I> in
<I>Bucuresti</I>";
($prim, $secund) = /<I>(.*?)<\/I>/ig;
print "Primul element: $prim, al doilea element: $secund.\n";
($prim, @rest) = /<I>(.*?)<\/I>/ig;
print "Primul element: $prim, restul " . "@rest" . ".\n";
($prim, @sir, $ultim) = /<I>(.*?)<\/I>/ig;
print "Primul element: $prim; ultimul element $ultim \n";
@rezultat = /<I>(.*?)<\/I>/ig;
print "Rezultatul este: @rezultat.\n";

Exista posibilitatea de a memora separat elemente ale sirului ntors ca rezultat, ca de


exemplu $prim si $secund. Atentie nsa ca variabila $ultim va ramne nedefinita deoarece
sirurile sunt lacome.
Numarul de siruri de caractere care satisfac expresia regulata de cautare se poate obtine n
doua moduri diverse:
$_ = "Piesa de teatru <I>Azilul de noapte</I> am vazut-o ieri la <I>Notara</I> in
<I>Bucuresti</I>";
$total++ while /<I>.*?<\/I>/ig;
print "Numarul de match-uri: $total.\n";
sau:
$_ = "Piesa de teatru <I>Azilul de noapte</I> am vazut-o ieri la <I>Notara</I> in
<I>Bucuresti</I>";
$total = s/<I>(.*?)<\/I>/<I>$1<\/I>/ig;
print "Numarul de match-uri: $total.\n";
Extinderi ale expresiilor regulate introduc noi facilitati care pot fi extrem de utile, de
exemplu, n cadrul substitutiei. Substitutia unui anumit cuvnt poate fi conditionata de faptul ca
el este urmat sau nu de un anumit caracter sau de un anumit cuvant. n acest caz este utila
explorarea anticipata a frazei sau sirului de cautare fara nsa ca acest ultim caracter sau cuvnt sa
fie memorat n variabila $& (variabila care contine sirul de caractere corespunzator expresiei
regulate de cautare).
(?= ...) permite indicarea caracterului sau cuvntului care urmeaza dupa stringul de cautare;
(?! ...) permite indicarea caracterului sau cuvntului care nu trebuie sa urmeze stringului de
cautare.
Un exemplu de aplicatie care foloseste aceste mecanisme este verificarea existentei
semnului de punctuatie ";" la sfrsitul fiecarei linii de cod dintr-un program C, Java sau Perl.
Evident este un exemplu trivial care nu ia n consideratie faptul ca pot exista linii de cod ce nu se
termina cu ";".
$_= "x = 1;\n y = 2\n z = 3\n";
$nr = s/(\w)(?=\n)/\1;/ig;
print "Numarul de modificari: $nr\n";
print "Rezultat:\n $_\n";
Analog se utilizeaza si constructia negativa, specificnd caracterul sau caracterele care nu
trebuie sa urmeze expresiei de cautat. Atentie nsa: aceste expresii nu pot fi utilizate pentru
specificarea unei eventuale constructii care trebuie sau nu trebuie sa preceada expresia de cautat.

Cteva exemple de utilizare a functiei de substitutie:


# Utilizarea parantezelor rotunde ca delimitatori:
s(/usr/bin)(/usr/local/bin);
# Utilizarea variabilelor n cadrul substitutiei:
s/Login: $var1/Login: $var2/;
# Memorarea numarului de nlocuri:
$nr_inlocuiri = ($linie =~s/Mister\b/Mr. /g);
# Utilizarea unei expresii ca expresie de nlocuire:
$_ = Pret = 111';
s/\d+/$&*2/e; # Pret = 222;
s/\w/$& x 2/eg; # Pprreett == 222222;
# Eliminarea spatiilor de la nceputul si sfrsitul unei linii:
s/^\s*(.*?)\s*$/\1/;
# Interschimbarea primelor doua cuvinte:
s/([^ ]*) *([^ ]*/\2 \1/;
Functia care realizeaza traducerea caracter cu caracter se numeste "tr" si are urmatoarea
forma generala:
tr/caractere_de_cautare/caractere_de_nlocuire/cds
unde:
c - indica complementarea setului de caractere de cautare; n acest caz lista efectiva a
caracterelor de cautare va contine toate caracterele care nu sunt specificate n cadrul setului
"caractere_de_cautare";
d - indica stergerea tuturor caracterelor din setul de "caractere_de_cautare" care nu au
corespondent n setul de "caractere_de_nlocuire";
s - indica reducerea secventelor de caractere care au fost traduse cu acelasi caracter la o
singura aparitie a respectivului caracter.
Aceasta functie practic nu foloseste expresiile regulate: stringul de intrare este parcurs
caracter cu caracter, nlocuind orice aparitie a unui caracter de cautare cu corespondentul sau de
nlocuire. Functia ntoarce numarul de caractere nlocuite si/sau sterse.

O particularitate a functiei de traducere este aceea ca cele doua seturi de caractere pot avea
proprii lor delimitatori care pot fi diferiti:
tr[a-z][A-Z]
tr(+-)/-+/
Cele doua seturi de caractere pot fi de lungimi diferite cu mentiunea ca setul de caractere
de cautare este ntotdeauna mai mare sau egal cu cel al caracterelor de nlocuire. n cazul n care
lista caracterelor de cautare este mai scurta dect lista caracterelor de nlocuire, comportamentul
functiei de traducere depinde de prezenta modificatorului "d" astfel:
- absenta modificatorului "d" implica replicarea ultimului caracter din lista de nlocuire
pna cnd cele doua liste ajung la aceeasi lungime:
- prezenta modificatorului "d" indica stergerea caracterelor care nu au corespondent n lista
de nlocuire:
$s = "Program Perl";
$s =~ tr/P/p/;
print "$s\n"; # Afiseaza: program perl
$s =~ tr/pr/rp/;
print "$s\n"; # Afiseaza: rpogpam repl
$s =~ tr/pr/?/;
print "$s\n" # Afiseaza: ??og?am ?e?l
$s =~ tr/ogamel?/OGAMEL/d;
print "$s\n"; # Afiseaza: OGAM EL
Lista caracterelor de cautare poate contine una sau mai multe aparitii ale aceluiasi caracter,
caz n care traducerea se realizeaza doar prin corespondentul primei aparitii a caracterului.
Exemplul:
tr/aaa/123/
va face traducerea literei "a" n cifra "1".
Corespondenta ntre caracterele de cautare si cele de nlocuire se stabileste la compilare.
Aceasta implica utilizarea functiei eval daca se doreste folosirea varibilelor n cadrul functiei de
traducere.
eval "tr/$lista_de_cautare/$lista_de_nlocuire"
Cteva exemple de utilizare a functiei de traducere:

tr/A-Z/a-z/
# Traducerea literelor majuscule n
# litere minuscule din variabila $_.
$nr = $dat =~ tr/=/=/
# Numararea semnelor de egalitate din
# variabila $dat.
tr/a-zA-Z//s
# nlocuirea aparitiilor succesive ale
# aceluiasi caracter cu o singura
# aparitie: "buuumm" devine "bum"
tr/a-zA-Z/ /cs
# Traducerea tuturor caracterelor care nu
# sunt litere in spatii.

Split
Divizarea unui string dupa o expresie regulata se realizeaza apelnd la functia split. Cu
ajutorul acestei functii, un cuvnt poate fi despartit n caractere, o propozitie poate fi despartita n
cuvinte, iar un paragraf n propozitii sau chiar cuvinte:
@caractere = split(//, $cuvant);
@cuvinte = split(/ /, $propozitie);
@propozitii = split(/\./, $paragraf);
Dupa cum se poate lesne deduce, functia split primeste doua argumente: delimitatorul dupa
care se face mpartirea stringului, si stringul respectiv. n cazul obtinerii sirului de caractere al
unui cuvnt, delimitatorul este sirul vid. n cel de-al doilea caz s-a considerat ca toate cuvintele
propozitiei sunt despartite de spatii, iar n cel de-al treilea caz ca propozitiile sunt despartite de
".".

Un argument n plus n favoarea Perl


O problema celebra n domeniul prelucrarii limbajului natural este de a cauta n cadrul
textelor mari si foarte mari, o anumita expresie regulata (de exemplu, unul sau mai multe cuvinte
care apar ntr-o anumita ordine: "Perl ... PCReport"), si de a afisa sirurile de caractere gasite,
mpreuna cu un context mimim n care acestea apar. Afisarea ar trebui sa alinieze n aceeasi
coloana primele cuvinte din sirurile de caractere care satisfac expresia regulata, n vederea
prelucrarii rapide a rezultatului.

Problema nu este complicata si nici greu de rezolvat. ncercati sa o rezolvati utiliznd


limbajul C sau Java. Veti constata ca timpul alocat rezolvarii se masoara n ore si ca lungimea
programului nu este deloc neglijabila.
n schimb, un programator de Perl rezolva aceeasi problema n cteva minute, iar lungimea
programului este mult mai mica n comparatie cu implementarea din C sau Java. Pentru a va
convinge de acest adevar atasam n listing 2 implementarea problemei n limbajul Perl.

Referine n perl
O referin Perl este un tip de date scalar care pstreaz locul unei alte valori, care putea fi
de tip scalar, array, sau hash. Din cauza naturii sale scalare, o referin poate fi folosit n toate
situaii unde un scalar poate fi folosit.
Este posibil de construi liste care conin referinele la alte liste, care pot conine referiri la
hash-uri, i aa mai departe. Acesta este modul n care structurile de date imbricate sunt
construite n Perl.
n Perl 5 exist 2 tipuri de referine: Hard i Symbolic. O referin simbolic conine
numele unei variabile. Referine simbolice sunt utile pentru crearea numelor de variabile i
adresarea lor la rulare. Practic, un link simbolic este ca numele unui fiier sau un link moale ntrun sistem UNIX. Referine Hard sunt mai mult ca link-uri dure n sistemul de fiiere.
Perl 4 permite numai referine simbolice, care este dificil de utilizat. De exemplu, n Perl 4,
este necesar de utilizat nume la index pentru un tablou asociativ numit _main {} de nume de
simbol pentru un pachet. Perl 5 permite referine Hard la date.
Referine Hard in evidena de numrului de referine. n cazul n care numrul de referin
devine zero, Perl elibereaz automat elementul la care erau fcute referine. Dac acel element se
ntmpl s fie un obiect Perl, obiectul este distrus, i ters din memorie. Perl este, n sine,
orientat pe obiecte, deoarece totul n Perl este un obiect. Pachete i module fac mult mai uor
utilizarea obiectelor n Perl.
Utilizarea referinelor Hard n Perl este simpl, atta timp ct sunt utilizate ca scalare.
Pentru a utiliza referine Hard de alt tip, diferit de cel scalar, este necesar ntr-un mod explicit de
a face derefencing-ul la variabil indicarea a modului n care ea trebuie s se comporte.

Crearea referinelor:
Este simplu de creat o referin pentru orice variabil, subrutina sau valoare prin prefixarea
cu o bar oblic invers, dup cum urmeaz:
$scalarref = \$foo;
$arrayref = \@ARGV;
$hashref = \%ENV;
$coderef = \&handler;
$globref = \*foo;
Nu este posibil de creat o referint la un IO handle (filehandle sau dirhandle) folosind
operatorul de backslash, ci o referin la un tablou anonim pot fi create folosind paranteze drepte,
dup cum urmeaz:
$arrayref = [1, 2, ['a', 'b', 'c']];

n mod similar se poate de creat o referin la un hash anonim folosind acolade dup cum
urmeaz:
$hashref = {
'Adam' => 'Eve',
'Clyde' => 'Bonnie',
};
O referire la o subrutina anonim poate fi creat folosind o subrutin fr nume, dup cum
urmeaz:
$coderef = sub { print "Boink!\n" };

Dereferencing
Dereferencing-ul ntoarce valoarea la locaia creia referina se refer. Pentru a face un
dereferencing se utilizeaz $, @ sau% ca prefix al variabilei de referin, n funcie de faptul
dac este referina indic la un scalar, o matrice, sau un hash. n urma este un exemplu pentru a
explica conceptul:
#!/usr/bin/perl
$var = 10;
# Now $r has reference to $var scalar.
$r = \$var;
# Print value available at the location stored in $r.
print "Value of $var is : ", $$r, "\n";
@var = (1, 2, 3);
# Now $r has reference to @var array.
$r = \@var;
# Print values available at the location stored in $r.
print "Value of @var is : ", @$r, "\n";
%var = ('key1' => 10, 'key2' => 20);
# Now $r has reference to %var hash.
$r = \%var;
# Print values available at the location stored in $r.
print "Value of %var is : ", %$r, "\n";
Cind programul de mai sus executat el d urmtorul rezultat:
Value of 10 is : 10
Value of 1 2 3 is : 123
Value of %var is : key220key110
Duc nu se tie sigur tipul variabilei atunci este uor de aflat folosind referin, care
returneaz unul dintre urmtoarele string-uri dac argumentul su este o referin. n caz contrar
se returneaz FALSE:
SCALAR
ARRAY

HASH
CODE
GLOB
REF

Referine circulare
Referinele circulare apar atunci cnd dou referine se adreseaz una la alta. Este necesar
de a fi atent cu referinele circulare, deoarece ele pot provoca la scurgeri de memorie. Un
exemplu:
#!/usr/bin/perl
my $foo = 100;
$foo = \$foo;
print "Value of foo is : ", $$foo, "\n";
Programul va afia:
Value of foo is : REF(0x9aae38)
Rferine la funcii
Acest lucru s-ar putea ntmpla n cazul n care este nevoie de a crea un handler de semnal,
astfel nct s fie posibil de a produce o referin la o funcie prin adugarea prefixului \$ la
denumirea acestei funciei i pentru aface dereferencing la aceasta funcie este pur i simplu
necesar de a aduga la variabile de referin simbolul $ :
#!/usr/bin/perl
# Function definition
sub PrintHash{
my (%hash) = @_;
foreach $item (%hash){
print "Item : $item\n";
}
}
%hash = ('name' => 'Tom', 'age' => 19);
# Create a reference to above function.
$cref = \&PrintHash;
# Function call using reference.
&$cref(%hash);
La executare programul afieaz:
Item : name
Item : Tom
Item : age
Item : 19

Programul
Sarcina personal: Proiectarea unui program n Perl
Structura programului: Subrutine elaborate de student care se apeleaza din meniu.
Funcionaliti realizate de subrutine:
1. Crearea fiierului F1 care va conine textul introdus de la tastatur.
2. Citirea i prelucrarea fiierului F1 conform sarcinii individuale (m/
(Cutarea n text a Substantivelor i a numerelor de nmatriculare auto)
3. Formarea listei L1 n memoria operativ n care se vor pstra rezultatele din .2.
4. Prelucrarea listei L1 (Sortarea n ordinea lexicografic a cuvintelor)
5. nregistrarea listei prelucrate n fiierul F2.
6. Citirea fiierului F2 n tabela H1 (cheile se introduc de utilizator)
7. Prelucrarea tabelei H1 (Afiarea cheilor care corespund valorilor m/) /)
8. nregistrarea n fiierul F3 a rezultatelor obinute n punctul 7.
9. Ieire din program.
Cercetare individual: Referine.

Listing-ul programului:
no warnings 'deprecated';
# Meniul principal
{
MENU:
print
"=============================================
=====\n";
print "=
=\n";
print "= 1 : Creati fisierul F1.txt
=\n";
print "= 2 : Cititi si modificati fisierul F2.txt
=\n";
print "= 3 : Cititi fisierul F2.txt
=\n";
print "= 0 : Iesiti din program
=\n";
print "=
=\n";
print
"=============================================
=====\n \n \n \n";
}
print "Alegeti o optiune: ";
$menu = <STDIN>;
if ($menu == "1") {functia1();}
if ($menu == "2") {functia2();}
if ($menu == "3") {functia3();}
if ($menu == "0") {iesire();}
#cream F1.txt si introducem textul de la tastiera
sub functia1
{
print "1 : Crearea fisierului F1 \n";
print "\n Introduceti textul: ";
$text = <STDIN>;
my $f1 = 'F1.txt';
open(my $fh, '>', $f1) or die "Eroare, '$f1' nu poate fi deschis!";
print $fh $text;
close $fh;
print "Succes. Fisierul F1.txt a fost creat!\n";
goto MENU;
}
#cream F2.txt si copiem substantivele si numere de masini din F1.txt si le
sortam
sub functia2
{
open FILE, "F1.txt" or die "Eroare, FILE nu poate fi deschis!";
$string = join("", <FILE>);
close FILE;
@listafinal = ();
@lista = split (/\s+/,$string);
foreach (@lista)

{
# Atribuim variabilei $cuv, elementul curent din lista
$cuv = $_;
# Verificam daca elementul curent incepe cu o majuscula, prima
litera e C,K, sau 2 litere majuscule, urmate de "-", urmat de 2 litere
majuscule, urmate de "-", urmat de 3 cifre (ex. C-NF-042, CH-AY-605)
#sau cuvinte ce sunt scrise intre ""
if ((substr($cuv, 0, 1) =~ /([A-Z])/g) || ($cuv =~ /([C|K|[A-Z]+[AZ])+[-]+([A-Z]+[A-Z])+[-]+[0-9]+[0-9]+[0-9]/g) || ($cuv =~ /(["])+[\w]+
["]/g))
{
push (@listafinal, $cuv);
}
}
print "\n \n \n Lista substantivelor proprii si a nr. de inmatriculare
auto: \n \n";
print "@listafinal \n";
print "\n \n \n Sortam lista in ordine alfabetica: \n \n";
@listafinal = sort @listafinal;
print "@listafinal \n";
print "\n \n Doriti sa salvati lista sorata in fisier ? (Y/N)";
$salvam = <STDIN>;
chomp $salvam;
if ($salvam eq "Y")
{print $salvam;
open my $fh, '>', "F2.txt" or die "Eroare, $fh nu poate fi
deschis!";
foreach (@listafinal)
{
print $fh "$_\n";
}
close $fh;
print "Fisierul F2.txt a fost creat cu succes !\n";
goto MENU;
}
else
{
goto MENU;
}
}
#introducem cheiele pentru elementele din F2.txt si le vizualizam in forma
de tabel
sub functia3
{
open FILE, "F2.txt" or die "Eroare, F2.txt nu poate fi deschis!";
$f2string = join("", <FILE>);
close FILE;
@f2list = split (/\s+/,$f2string);
my $arrSize = @f2list;
for (my $i=0; $i<$arrSize; $i++)
{

print "Introduceti cheia p/u $f2list[$i]: ";


$chei[$i] = <STDIN>;
chomp $chei[$i];
}
for (my $i=0; $i<$arrSize; $i++)
{
$H1[$i][0] = $chei[$i];
}
for (my $i=0; $i<$arrSize; $i++)
{
$H1[$i][1] = $f2list[$i];
}
for (my $i=0; $i<$arrSize; $i++)
{
for (my $j=0; $j<2; $j++)
{
print "$H1[$i][$j] \t";
}
print "\n";
}
print "\n \n Doriti sa salvati tabelul in fisier ? (Y/N)";
$salvam = <STDIN>;
chomp $salvam;
if ($salvam eq "Y")
{
open my $fh, '>', "F3.txt" or die "Eroare, F3.txt nu poate fi
deschis!";
for (my $i=0; $i<$arrSize; $i++)
{
for (my $j=0; $j<2; $j++)
{
print $fh "$H1[$i][$j] \t";
}
print $fh "\n";
}
print "Succes!\n";
goto MENU;
} else {
goto MENU;
}
}
sub iesire
{
exit;
}
$t = <STDIN>;

Screenshoturi:

Meniul principal

Crearea fiierului F1.txt i introducerea coninutului

Prelucrarea F1.txt, selectarea substantivelor i numerelor de nmatriculare


auto i sortarea lor cu salvarea n F2.txt

Prelucrarea F2.txt cu atribuirea cheilor, afiarea tabelului cu elentele si cheile


corespunztoare i salvarea n F3.txt

Concluzie:

n lucrarea dat a fost creat un script n perl care permite prelucrarea datelor
introduse de utilizator i identificarea substantivelor i numerelor de
nmatriculare auto. Pentru aceasta au fost folosite expresii regulate care
reprezint un instrument flexibil de cutare.

Bibliografie
http://www.scritub.com/stiinta/informatica/Introducere-inPERL921271914.php

http://perldoc.perl.org/index-language.html
http://www.tutorialspoint.com/perl/perl_formats.htm
https://www.cs.tut.fi/~jkorpela/perl/regexp.html

Aprob
eful catedrei IA
dr., conf. univ. ___________________V.Moraru

Sarcina
proiectul de an la disciplina
Programarea bazat pe reguli i expresii regulare
Studentul grupei MAI-131 Pivovarcic Serghei
TEMA: Proiectarea i elaborarea unui program Perl
Domeniul de aplicare:

prelucrarea textelor n limbaj natural

Structura programului:

subrutine elaborate de student care se apeleaz din meniu

Funcionaliti realizate de subrutine:


1. Crearea fiierului F1 care va conine textul introdus de la tastatur.
2. Citirea i prelucrarea fiierului F1 conform sarcinii individuale (m/
/)
(Cutarea n text a Substantivelor i a numerelor de nmatriculare auto)
3. Formarea listei L1 n memoria operativ n care se vor pstra rezultatele din .2.
4. Prelucrarea listei L1 (Sortarea n ordinea lexicografic a cuvintelor)
5. nregistrarea listei prelucrate n fiierul F2.
6. Citirea fiierului F2 n tabela H1 (cheile se introduc de utilizator)
7. Prelucrarea tabelei H1 (Afiarea cheilor care corespund valorilor m/) /)
8. nregistrarea n fiierul F3 a rezultatelor obinute n punctul 7.
9. Ieire din program.
Cercetare individual: Referine.

Data nmnrii sarcinii


Semntura studentului

10.04.2014
______________________
Data limit de prezentare 06.06.2014

Conductorul proiectului
Conf.univ.

Liviu Carcea

CHIINU 2014

S-ar putea să vă placă și