A Perl programozási nyelv röviden 79/1

Hasonló dokumentumok
Szkriptnyelvek II. Perl programok

Szkriptnyelvek. 1. UNIX shell

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

AWK programozás, minták, vezérlési szerkezetek

file./script.sh > Bourne-Again shell script text executable << tartalmat néz >>

BASH script programozás II. Vezérlési szerkezetek

AWK programozás, minták, vezérlési szerkezetek

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

1. Alapok. #!/bin/bash

AWK programozás Bevezetés

S z á m í t ó g é p e s a l a p i s m e r e t e k

BASH SCRIPT SHELL JEGYZETEK

Programozás II. 2. Dr. Iványi Péter

Forráskód formázási szabályok

Java II. I A Java programozási nyelv alapelemei

C programozás. 1 óra Bevezetés

HORVÁTH ZSÓFIA 1. Beadandó feladat (HOZSAAI.ELTE) ápr 7. 8-as csoport

Operációs rendszerek. 9. gyakorlat. Reguláris kifejezések - alapok, BASH UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Webprogramozás szakkör

8. Laboratóriumi gyakorlat: Bevezetés a reguláris kifejezések használatába

Bevezetés a programozásba. 8. Előadás: Függvények 2.

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Python tanfolyam Python bevezető I. rész

Operációs rendszerek gyakorlat

Listák, szótárak, fájlok Listák, szótárak, fájlok

PHP. Telepítése: Indítás/újraindítás/leállítás: Beállítások: A PHP nyelv

7. Laboratóriumi gyakorlat: Vezérlési szerkezetek II.

Tömbök kezelése. Példa: Vonalkód ellenőrzőjegyének kiszámítása

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

Informatika terméktervezőknek

Programozási segédlet

8. Laboratóriumi gyakorlat: Bevezetés a reguláris kifejezések használatába

Operációs rendszerek gyak.

Bevezetés a programozásba I 4. gyakorlat. PLanG: Szekvenciális fájlkezelés. Szekvenciális fájlkezelés Fájlok használata

Programozás II. 4. Dr. Iványi Péter

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Operációs rendszerek. 9. gyakorlat. BASH recap, reguláris kifejezések UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

8. gyakorlat Pointerek, dinamikus memóriakezelés

II. Mérés SZÉCHENYI ISTVÁN EGYETEM GYŐR TÁVKÖZLÉSI TANSZÉK

Bevezetés a programozásba I 4. gyakorlat. PLanG: Szekvenciális fájlkezelés

A programozás alapjai

Flex tutorial. Dévai Gergely

Java II. I A Java programozási nyelv alapelemei

Szövegek C++ -ban, a string osztály

Adattípusok, vezérlési szerkezetek. Informatika Szabó Adrienn szeptember 14.

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Gyakorló feladatok Gyakorló feladatok

Operációs Rendszerek II. labor. 2. alkalom

A JavaScript főbb tulajdonságai

Járműfedélzeti rendszerek II. 1. előadás Dr. Bécsi Tamás

1. Jelölje meg az összes igaz állítást a következők közül!

Készítette: Nagy Tibor István

Karakterkészlet. A kis- és nagybetűk nem különböznek, a sztringliterálok belsejét leszámítva!

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Programozás C++ -ban 2007/1

Operációs rendszerek. 10. gyakorlat. AWK - bevezetés UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

Java programozási nyelv

Occam 1. Készítette: Szabó Éva

Kifejezések. Kozsik Tamás. December 11, 2016

A C# programozási nyelv alapjai

A C programozási nyelv I. Bevezetés

Programozás Minta programterv a 1. házi feladathoz 1.

sallang avagy Fordítótervezés dióhéjban Sallai Gyula

Az alábbi kód egy JSON objektumot definiál, amiből az adtokat JavaScript segítségével a weboldal tartalmába ágyazzuk.

A C programozási nyelv I. Bevezetés

OOP #14 (referencia-elv)

2018, Funkcionális programozás

1. Alapok. Programozás II

Járműfedélzeti rendszerek II. 2. előadás Dr. Bécsi Tamás

Programozás C és C++ -ban

Bevezetés a programozásba I.

Óbudai Egyetem. C programozási nyelv

8. Laboratóriumi gyakorlat: Bevezetés a reguláris kifejezések használatába

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

Vezérlési szerkezetek

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Programozási nyelvek (ADA)

Máté: Assembly programozás

Programozás I gyakorlat. 10. Stringek, mutatók

Kifejezések. Kozsik Tamás. December 11, 2016

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

ELTE SAP Excellence Center Oktatóanyag 1

Alapok. tisztán funkcionális nyelv, minden függvény (a konstansok is) nincsenek hagyományos változók, az első értékadás után nem módosíthatók

Komputeralgebra rendszerek

Komputeralgebra rendszerek

Reguláris kifejezések 1.

PYTHON. Avagy hosszú az út a BioPythonig

Mintavételes szabályozás mikrovezérlő segítségével

7. fejezet: Mutatók és tömbök

Bevezetés a programozásba I.

C programozási nyelv

Segédanyagok. Formális nyelvek a gyakorlatban. Szintaktikai helyesség. Fordítóprogramok. Formális nyelvek, 1. gyakorlat

ALGORITMIKUS SZERKEZETEK ELÁGAZÁSOK, CIKLUSOK, FÜGGVÉNYEK

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

6. fejezet: Ciklusok

Programozás C++ -ban 2007/7

A C programozási nyelv VI. Parancssori argumentumok File kezelés

Megjegyzés: A programnak tartalmaznia kell legalább egy felhasználói alprogramot. Példa:

Regionális forduló november 19.

Átírás:

A Perl programozási nyelv röviden 79/1 A Perl nyelvről általában A Perl egy olyan programozási nyelv, amelyet eredetileg arra találtak ki, hogy UNIX adminisztrációs feladatokat lehessen vele automatizálni, aztán egy kicsit kinőtte magát. Általában értelmezett (interpretált), de éppen napjainkban készül hozzá fordító program, amely C nyelvre fogja fordítani. Egyelőre maradjunk az értelmezett változatnál, és ebben gondolkodjunk. Ha eddig azt gondoltad, hogy a PASCAL a szépen és dokumentáltan programozható nyelv, és C-ben kegyetlenül olvashatatlan programokat lehet írni, akkor most értékeld át a dolgot: PASCAL-ban szépen formátumozott programokat lehet írni, C-ben olvashatatlan és Perl-ben kegyetlenül olvashatatlan programokat. Lehet. De nem kell. A nyelv neve egy rövidítés: Practical Extracting and Reporting Language, vagyis praktikus szerkesztő és jelentéskészítő nyelv. Eredetileg. De egyesek szerint ez csak azt fejezi ki, hogy mi volt a nyelv teremtőinek célja; az eredményt jobban kifejezi a Pathologically Eclectic and Rubbis Lister, ami magyarul csak annyit tesz, hogy betegesen túldíszített szemét listázó. Nos, mindenki eldöntheti, hogy melyik az saját szájízének megfelelő. Helló világ! Igen, ez a szokásos bevezető gyakorlat, amelyik semmi mást nem is csinál, mint kiírja a képernyőre, vagy a szabvány kimenetre, hogy Hello világ! Hát itt is van: print "Helló világ!\n"; És utána itt van az eredmény is: Helló világ! Persze ez nagyon egyszerű. A print beépített parancs kiírja az argumentumait a szabványos kimenetre. Aki programozott C-ben, annak ismerős lehet a \n karakter is, amelyik egy sort emel (újsor karakter). Félre a tréfával! Nézzünk valami komolyabbat! $a = 123; $b = 55; $c = $a + $b; $d = "kakukk\n"; $d = 'kakukk\n' if $c == 178; if( $d eq "kakukk\n" ){ print "Helló világ!\n"; else{ print "Ma nincs jó napod!\n" Itt mindjárt látunk is valamit. Például azt, hogy minden egyes változó neve előtt van egy dollár $ jel. Így nincs gond azzal, hogy egy név lefoglalt változó-e, vagy sem. Így lehet használni nyugodtan mindenféle változót, így akár a következőket is: $if $else $return $unless $while $or $and Ezek egyébként mind lefoglalt szavak lennének, ha lenne ilyen fogalom a Perl nyelvben. Az első három sor nem érdekes. A negyedik egy string értékadás, amelyik a $d változónak ad egy string értéket. Ez a string a k a k u k k karakterek és egy újsor karakter. A következő sorban levő utasítás először megvizsgálja, hogy a $c változó értéke 178-e. Rövid fejszámolás után kideríthetjük, hogy igen, bár az ilyen műveletek elvégzésére még a Perl is jobb nálam. A $d itt tehát új értéket kap. Ez az új érték azonban nem egyezik meg azzal, amit az előbb kapott (ennek nem is lenne semmi értelme, még egy ilyen

A Perl programozási nyelv röviden 79/2 tanmesében sem). Az új érték a k a k u k k \ n karakterek, azaz nyolc karakter. Mitől? Miért fordított törtvonal, és n karakter van a füzér végén, és miért nem újsor karakter? A magyarázat az idézőjelek helyett használt aposztrófokban rejlik. Ha idézőjelet használunk, akkor a Perl értelmezi a stringet, az escape karaktereket éppen úgy, mint például a füzérben előforduló változókat (miket??? türelem!). Ha azonban aposztrófokat használunk, akkor mindez nem történik meg, a füzér úgy van, ahogy leírtuk, se több, se kevesebb. Na, haladjunk tovább. Ezek után már senkit sem lep meg, hogy amit kiír a program, az nem az előző "Hello világ!", hanem az, hogy Ma nincs jó napod! ami ugye nem igaz, mert máris rengeteg érdekes dolgot tanultál meg a Perl nyelvről. Ha részletesebben is érdekel a dolog, akkor visszamehetsz a nyitó oldalra, vagy innen is továbbléphetsz és olvashatsz a Perl változókról, a különböző program szerkezetekről vagy a stringekről, hogy csak néhányat említsünk azok közül, amik ebben az ízelítőben előjöttek. Perl változók A Perl nyelvben háromféle változó van: skalár ($) tömb (@), és hash (%) A változók nincsenek előre deklarálva, és bármelyik változó tárolhat füzért, egész számot, mutatót (ezek mind skalár értékek) akár ugyanaz a változó is egymás után hol ilyent, hol meg amolyant. Az is lehetséges, hogy egy tömb, vagy egy hash egyik eleme füzért, egy másik eleme számot egy harmadik meg akár mutatót tárol. Bármilyen alfanumerikus karaktersorozat lehet változónév, még kulcsszó is, mint a $if $else $return $unless $while $or $and mivel ezeket a Perl nem foglalja le magának. Amiket előre lefoglal, azok az olyan változók, mint a $/, vagy $, meg a társaik. Ezeknek speciális jelentésük van. Amivel leggyakrabban fogsz találkozni ezek közül az a $_, amelyik a default változó. (Egy csomó függvénynél, program szerkezetnél ha nincs megadva valamelyik szerepre változó, akkor a Perl a $_ változót használja.) A tömbváltozókat onnan lehet megismerni, hogy ezek előtt nem $ hanem @ jel van. Ezeknek is lehet értéket adni, de természetesen nem skalár, hanem tömb értéket, például: @tomb = (1, 2, 3); Itt a @tomb egy tömbváltozó, amelynek van három eleme. Az egyes elemekre a PASCAL, vagy C nyelvben megszokott módon lehet hivatkozni a [ és ] zárójelek használatával. Viszont ilyenkor már egy elemre hivatkozunk, ami nem tömb, hanem skalár, tehát ilyenkor már a $ jelet kell a változó elé írni: $tomb[0] ami a @tomb tömbváltozó első elemét jelenti. (Hacsak a $[ változónak valahol nullától eltérő értéket nem adtunk.) A hash változó hasonlít a tömbhöz, de nem nullától n-ig megy az index, hanem bármilyen értéket felvehet. Lehet az index szám, string, mutató, vagy bármilyen más skalár érték. Amikor az egész hash változóra hivatkozunk, akkor % jelet írunk elé, amikor pedig az egyes elemeire, akkor $ jelet, mivel ilyenkor már egy eleme skalár érték. Az értékadás nagyon hasonló a tömb értékadáshoz:

A Perl programozási nyelv röviden 79/3 %tomb = (1, 2, 3,4 ); ami egy két elemű hash. Az egyik elem indexe 1, a másiké 3. Az egyik értéke 2, a másiké 4. Persze ez így elég olvashatatlan, és ezért a Perl nyelv nyújt egy sokkal olvashatóbb szintaxist is: %tomb = ( 1 => 2, 3 => 4, ); A hash egyes elemeire pedig úgy lehet hivatkozni, mint a tömb elemeire, de nem szögletes, hanem kapcsols zárójelet kell használni: $tomb{1 aminek az értéke a példánál maradva 2. És most tessék kapaszkodni, mert kihajolni veszélyes!! A következő változók mind használhatók egy programon belül: %valtozo $valtozo @valtozo És ezek mindegyike másik változó, sőt még ilyen nevű szubrutin is lehet! Ezek után nem lehetetlen a következő rövid program darab: %valtozo = ( 'alma' => 'gyimilcs', 'kutya' => 'allat', ); $valtozo = 3.14; @valtozo = (55,13,32); ami eddig mind más változónak adott értéket, de ezt még fokozhatjuk: $valtozo[4]=$valtozo; aminek a hatására a @valtozo tömb mérete automatikusan megnő, $valtozo[3] nem definiált értéket kap, $valtozo[4] viszont a Ludolf féle szám népszerű közelítő értékét kapja. Ezek után már senki sem csodálkozik azon, hogy a $valtozo=4; utasítás végrehajtása után akár a $valtozo{$valtozo=$valtozo[$valtozo]; utasítás is kiadható. Reguláris kifejezések, mintaillesztés

A Perl programozási nyelv röviden 79/4 A Perl nyelv egyik, ha nem a legnagyobb erőssége az igen fejlett mintaillesztési lehetőség, vagy másképp fogalmazva a reguláris kifejezések kezelése. Persze a Perl nyelv előttjóval voltak már UNIX operációs rendszer alatt olyan eszközök, amelyek reguláris kifejezéseket használtak, de a Perl nyelvnél talán mindegyiknél jobb, és teljesebb lehetőségek vannak. Ha még nem használt soha reguláris kifejezéseket, akkor ennek a fejezetnek az elolvasása előtt ajánlott az m operátor illetve az s operátor fejezetek elolvasása. Ugyanakkor azok teljes megértéséhez szükséges ennek a fejezetnek az elolvasása. Így tehát nem tudom, hogy melyiket érdemes elolvasni először. Feltehetőleg az egyiket, aztán a másikat, és azután néhányszor újra. Bevezető Reguláris kifejezésre rendkívül egyszerű példát mutatni. A következő példa a @mail tömb elemeiről próbálja meg eldönteni, hogy jók lesznek-e email címnek. @mail = ( 'verhas@mail.digital.hu', 'hab.akukk%mikkamakka@jeno', ); for( @mail ){ if( /^.*@\w+\..+$/ ){ print "$_ jó email címnek látszik\n"; else{ print "$_ Ez nem jó cím\n"; Az első utasítás a @mail tömböt hozza létre. Ennek elemein megy végig a for ciklus, és minden egyes elemet megvizsgál, és megpróbálja eldönteni, hogy jó lesz-e elektronikus levélcímnek vagy sem. Mivela for ciklusnak nem adtunk meg változót, ezért a Perl a $_ változót használja ciklus változónak, és mivel az if utasításban sem adjuk meg, hogy mely változót akarjuk a reguláris kifejezéshez hasonlítani, ezért ez is ezt a változót használja. (Minő véletlen egybeesés.) A példabeli reguláris kifejezés szavakkal elmondva a következőt jelenti: a füzér kezdődjön ^ nulla vagy több bármilyen karakterrel.* utána következzen egy @ karakter majd legalább egy, vagy több betű \w+ majd egy pont \. végül még legalább egy vagy több bármilyen karakter.+ és legyen vége a füzérnek $. A kimenet: verhas@mail.digital.hu jó email címnek látszik hab.akukk%mikkamakka@jeno Ez nem jó cím A reguláris kifejezéseket, mint a fenti példában is látható használhatjuk arra, hogy bizonyos szintaktikus szabályoknak való megfelelést vizsgáljunk füzéreknél. Ehhez a m operátort használtuk a fenti példában. Magát az operátort azért nem kellett kiírni, mert a / jelet használtuk határolónak, a fűzért pedig azért nem, mert az a default változó, a $_ volt. Az if utasításbeli kifejezést írhattuk volna $_ =~ m/^.*@\w+\..+$/ alakban is. A másik lehetőség reguláris kifejezés használatára, amikor bizonyos részeket ki akarunk cserélni egy fűzérben. Nézzük példának a következő kis programot:

A Perl programozási nyelv röviden 79/5 $text = 'Java szigetén nem használnak JavaScript programokat.'; $text =~ s/java(?!script)/borneo/; print $text; aminek a kimenete Borneo szigetén nem használnak JavaScript programokat. Az s operátor egy reguláris kifejezést és egy interpolált füzért használ. Végignézi a változót, amely a példában $text és az első olyan részfüzért, amely megfelel a reguláris kifejezésnek kicseréli a második paraméterként megadott füzérre. Így lesz Java szigetéből Borneó. Érdemes megfigyelni, hogy ezeknél a műveleteknél nem = jelet használunk, hanem =~ operátort. Ezt pedig nem szabad összetéveszteni a ~= operátorral! (A nyelv szépségei!) Ha ugyanis valaki az előbbi példában a $text = s/java(?!script)/borneó/; írná, akkor a helyettesítési operátor (s///) nem a $text változót, hanem a default $_ változót keresné, amelyben nem talána egyetlen Java alfüzért sem, és visszatérési értékként üres füzért ad vissza. Más szavakkal: a program nem írna ki semmit, vagy precízebben semmit írna ki. Részletesen és precízen az m operátorról, és a s operátorról. Ezeket egy kicsit nehéz megérteni a reguláris kifejezések ismerete nélkül, de vígasztaljon, hogy a reguláris kifejezéseket pedig nehéz megérteni az m és az s operátorok ismerete nélkül. Amikor a Perl egy füzért megpróbál hozzáilleszteni egy reguláris kifejezéshez mind a füzérben, mind pedig a reguláris kifejezésben balról jobbra halad, egészen addig, amíg el nem ér a reguláris kifejezés vagy a füzér végére. Ha ekkor az egész reguláris kifejezést hozzá tudta illeszteni a füzérhez, akkor a füzér megfelel a reguláris kifejezésnek, ha nem, akkor pedig nem. (Például az m operátor igaz, vagy hamis értéket ad vissza.) A meta karakter fogalma Az illesztés során a reguláris kifejezésben minden közönséges karakter, amelyik nem metakarakter (definíció mindjárt) önnmagának felel meg. Ha tehát a reguláris kifejezés következő karaktere egy 'a' betű, akkor a füzér következő illesztendő karaktere is 'a' betű kell, hogy legyen. A metakarakterek speciális karakterek, amelyek a reguláris kifejezésben speciális jelentőséggel bírnak. Ilyen például a. pont, amely a füzérben bármilyen nem újsor karakternek megfelel. Egy másik speciális karakter a $ jel, amelyik a füzér végének, vagy a füzér végén lévő újsor karakternek felel meg. Hasonlóan a ^ karakter a füzér elejének felel meg. Ezt a viselkedést mind az m, mind pedig az s operátoroknál változtatni lehet az m és s opciókkal. Az m opció esetén a füzért többsorosnak tekinti a rendszer, ami praktikusan annyit jelent, hogy minden sor végét meg lehet találni a $ jellel, ami a reguláris kifejezésben a sor vagy a füzér végét jelenti, és hasonlóan minden sor elejét a ^ jellel. Ennek az ellentéte a s opció, amely esetben a füzért egysorosnak tekinti a Perl, és a $ csak a füzér végét fogja megtalálni, vagy a füzér végén álló soremelést a ^ jel pedig csak a füzér elejét úgy, mintha sem az s sem pedig a m opciót nem adtuk volna meg. Az s opció igazi értelme, hogy ennek megadásakor a reguláris kifejezésekben a. pont karakter megfelel a soremelés karaktereknek is, míg enélkül az opció nélkül ezeknek a karaktereknek nem felel meg ez a metakarakter. Az egyik legfontosabb metakarakter a \ amelyet ha egy metakarakter elé írunk a füzérben a karakter pontosan önnmagának fog megfelelni, így \. egy pontot jelent a füzérben vagy \\ egy fordított törtvonal karaktert. Ha nem metakarakter elé írjuk a fordított törtvonalat, akkor előfordulhat hogy más jelentést kap a karakter, például \t a tabulátor, vagy \w az betű karaktereknek felel meg, de erről még később. Zárójelek

A Perl programozási nyelv röviden 79/6 A zárójelek is speciális jelentéssel bírnak. Ezekkel a reguláris kifejezés egyes részeit lehet bezárójelezni, és ezekre a részekre lehet a későbbiekben hivatkozni a $1, $2,... változókkal a reguláris kifejezésen kívül, vagy a \1, \2,... referenciákkal a reguláris kifejezésen belül. Példaképpen $text = 'Java szigetén nem használnak szigonyt.'; $text =~ /(Ja(va)).*(szi).*\3(g(e o))/; print "$1 $2 $3 $4 $5\n"; kimenete Java va szi go o Látható, hogy a számozási sorrend a nyitó zárójelek szerint megy, és nem a záró zárójelek szerint. Ennek csak abban az esetben van jelentősége, ha, mint ebben a példában, egymásba vannak ágyazva a zárójelek. Lehetőség van arra is, hogy úgy zárójelezzünk be egy részt a reguláris kifejezésből, hogy az ne hozzon létre referenciát. Ehhez a (?: nyitó karakter sort és a szokásos ) zárójelet kell használni, például: $text = 'Java szigetén nem használnak szigonyt.'; $text =~ /(Ja(?:va vi)).*(szi).*\2(g(e o))/; print "$1 $2 $3 $4\n"; kimenete Java szi go o Itt rögtön látunk egy új metakaraktert, a jelet. Ez a jel választást jelent a bal és a jobb oldalán álló rész reguláris kifejezések közül bármelyik megfelelhet a füzér éppen soron levő darabjának. Karakter osztály Még egy érdekes zárójel van a reguláris kifejezésekben, a [ és ]. Ezek kartakter osztályokat fognak közre. Ha egy reguláris kifejezésben azt írjuk, hogy [acfer], akkor az az a, c, f, e és r betűk bármelyikének megfelel. Ugyanakkor rövidíthetünk is karakterosztályok megadásánál. Például [a-f] az összes a és f közötti karakternek felel meg, vagy [a-fa-f] ugyanez a karakter osztály, de a kisbetűk és a nagybetűk is. Ha a legelső karakter a karakterosztály megadásánál a [ karakter után egy ^ karakter, akkor a karakter osztály invertálódik, azaz [^a-f] bármilyen karakternek megfelel, kivéve az a és f közötti karaktereket. Karakterosztály megadásánál a karakter is közönséges karakternek számít. Ismétlés Egy reguláris kifejezés egy részére, vagy az egész reguláris kifejezésre előírhatjuk, hogy hányszor kell egymás után alkalmazni. Ezt a reguláris kifejezések ismétlést előíró modosítóival tehetjük meg, amelyeket mindig a reguláris (rész)kifejezés után kell írni. Ezek: * nulla vagy többszöri ismétlés + egy, vagy többszöri ismétlés? nulla, vagy egyszer {n pontosan n-szer {n, legalább n-szer {n,m legalább n-szer, de legfeljebb m-szer Ha a kapcsos zárójel bármilyen más környezetben fordul elő, akkor normál karakterként értelmezi a Perl. n és m nulla és 65,535 közötti értékek lehetnek. Alaphelyzetben ezek az ismétlési módosítók falánkak, és annyira előreszaladnak, amennyire csak lehet. Ezt lehet visszafogni azzal, ha az ismétlési módosító mögé egy? jelet írunk. Ekkor csak annyit ismételnek ezek a módosítók, amennyit feltétlenül kell. Példaképp egy reguláris kifejezés illesztés * és *? módosítóval 'Java szigetén nem használnak szigonyt.' =~ /Ja(.*)g(?:e o)/; print "$1\n";

A Perl programozási nyelv röviden 79/7 'Java szigetén nem használnak szigonyt.' =~ /Ja(.*?)g(?:e o)/; print "$1\n"; és a kimenete va szigetén nem használnak szi va szi Speciális karakterek Mivel a reguláris kifejezések mint interpolált füzérek kerülnek kiértékelésre, ezért a következők is használhatók: \t tabulátor (HT, TAB) \n újsor, soremelés (LF, NL) \r kocsivissza karakter (CR) \f lapdobás (FF) \a csengő (bell) (BEL) \e escape (ESC) \033 oktális kód megadása (mint a PDP-11 nél) \x1b hexa karakter \c[ kontrol karakter \l a következőkarakter kisbetűsre konvertálva \u a következő karakter nagybetűsre konvertálva \L kisbetűsek a következő \E-ig \U nagybetűsek a következő \E-ig \E kisbetű, nagybetű módosítás vége \Q reguláris kifejezések meta karakterei elé fordított törtvonalat ra a következő \E-ig Ezeken kívül a Perl még a következőket is definiálja \w egy szóban használható karakter (alfanumerikus karakterek és aláhúzás) \W minden ami nem \w \s szóköz fajta karakter, szóköz, tabulátor, újsor stb. \S minden ami nem \s \d számjeg \D nem számjegy Ezek a jelölések karakterosztályok megadásában is használhatók, de nem intervallum egyik végén. A következők is használhatók még reguláris kifejezésekben: \b szó határának felel meg \B nem szó határnak felel meg \A csak a füzér elején \Z csak a füzér végén \G ott folytatja ahol az előző m//g abbahagyta A \b karakterosztályban használva visszalépés karakternek felel meg. Egyébként mint szóhatár olyan helyet jelöl, ahol az egyik karakter \w és a mellette levő \W. Ennek eldöntésére a füzér elején az első karakter elé és a füzér végén az utolsó karakter utánra egy-egy \W karaktert képzel a rendszer. A \A és \Z ugyanaz, mint a ^ és a $ azzal a különbséggel, hogy ezek még a m opció használata esetén sem felelnek meg a füzér belsejében levő soremelés karakternek. Egyéb kiterjesztések A reguláris kifejezések a Perl nyelvben a szokásos egyéb UNIX eszközökhöz képest további kiterjesztéseket is tartalmaznak. Így reguláris kifejezésen belül lehet használni (?#megjegyzés) megjegyzéseket lehet a reguláris kifejezésekben elhelyezni. Amennyiben az x opciót használjuk egy sima # is megteszi. (?:regexp) Zárójelezett reguláris kifejezés, amely azonban nem generál referenciát, azaz nem lehet rá hivatkozni a $1, $2,... változókkal, illetve a \1,\2... visszahivatkozásokkal. Ugyanakkor nagyon hasznosak, akkor ha valamilyen alternatívát kell megadni a metakarakterrel.

A Perl programozási nyelv röviden 79/8 (?=regexp) Nulla hosszúságú előrenézés. Ezzel a konstrukcióval egy olyan rész reguláris kifejezést lehet megadni, amelyet a Perl leellenőriz, de mégsem vesz bele az illesztett listába. Például /\w+(?=\t)/ reguráris kifejezésnek egy olyan szó felel meg, amelyet egy tabulátor követ, a tabulátor azonban nem veszi figyelembe a Perl, csak megnézi, hogy ott van. Ha a helyettesítés operátort használjuk, akkor $t = 'jamaica rum rum kingston rum'; $t =~ s/([aeoui])(?=\w)/uc($1)/ge; print $t; kimenete jamaica rum rum kingston rum ami azt jelenti, hogy a mintaillesztés során a Perl megnézte, hogy betű áll-e a magánhangzó után, de azt a betűt, már nem tekintette az illesztett, és így helyettesítendő füzérdarab részének. Ennek megfelelően ez a kis programdarab minden olyan magánhangzót nagybetűre cserélt, amely nem szó végén állt. (?!regexp) Negatív nullahosszúságú előrenézés. Hasonló a (?=... )-höz, de akkor fogadja el a mintát, ha a következő füzérdarab nem felel meg a megadott reguláris kifejezésnek. Az előző példát használva és persze módosítva egy kicsit $t = 'jamaica rum rum kingston rum'; $t =~ s/([aeoui])(?!\w)/uc($1)/ge; print $t; kimenete jamaica rum rum kingston rum ami minden olyan magánhangzót cserél nagyra, amelyet nem betű követ. Nagyon fontos megjegyezni, hogy ezekkel a konstrukciókkal csak előre lehet nézni, visszafelé nem. Ha ugyanis azt írjuk, hogy (?!Borneo)Script, akkor az nem azt jelenti, hogy minden olyan Script amely előtt nem Borneo áll. Ez a reguláris kifejezés minden Script-et meg fog találni, a BorneoScript-eket is, illetve annak Script részét, hiszen amikor a (?!Borneo) részt értékeli ki a Perl azt fogja találni, hogy a vizsgált helyen nem Borneo áll, hanem Script. Ez így neki rendben van, megy tovább és ismételten látni fogja, hogy az adott helyen Script áll, ezt most már illeszti is a reguláris kifejezés további részéhez, hiába állt a Script előtt Borneo. (?imsx) Reguláris kifejezés értelmezését módosító opció megadása a reguláris kifejezésen belül. Ezeket az opciókat általában az m vagy s operátorok után szoktuk megadni, néha azonban szükség lehet, hogy magába a reguláris kifejezésbe kerüljön bele az opció. Ilyen lehet az, amikor a reguláris kifejezés egy változóban van megadva. Az egyéb opciók, mint az e vagy g nem adhatók meg a reguláris kifejezésen belül, hiszen ezek nem a reguláris kifejezésre vonatkoznak, hanem magára a m és s operátorok végrehajtására. Az opciókat érdemes a reguláris kifejezés elején megadni, mert különben igen érdekes, és meglehetősen nehezen értelmezhető hatásuk lesz, például a $t = 'jamaica rum rum kingston rum'; $t =~ s/(?i)ica/juli/g; $t =~ s/rum(?i)/bor/; print $t; hatására miért csak az utolsó rum-ból lesz bor: jamajuli rum rum kingston bor Visszalépéses kiértékelés Amikor a Perl egy reguláris kifejezést illeszt egy füzérhez az illesztés csak akkor sikeres, ha az egész reguláris kifejezést sikerült illesztenie. Amikor az illesztés során a mintaillesztő algoritmus előre halad, és valahol elakad, akkor még nem adja fel, hanem megpróbál visszalépni és újra próbálkozik. Így, amikor a $text = 'Java szigetén nem használnak JavaScript programokat.'; $text =~ s/java(?=script)/borneo/; print $text;

A Perl programozási nyelv röviden 79/9 példában elindul a mintaillesztés a Perl eljut egészen az első Java végéig, és illeszti a reguláris kifejezést. Itt azonban elakad, mert a (?=Script) megkövetelné, hogy a Java szó után a Script szó következzen. Ezért visszalép és próbálja a füzér további részéhez illeszteni a reguláris kifejezést, amíg el nem jut a JavaScript szóhoz, amelyhez sikerül az illesztés, és ennek megfelelően megtörténik a csere, így az eredmény Java szigetén nem használnak BorneoScript programokat. Egy másik példát megnézve $t = 'Mi van a jing és a jang között? Talán a Jangce?'; $t =~ /jing(.*)jang/i; print $1; az eredmény és a jang között? Talán a Ennek az az oka, hogy amikor a jing szót megtalálja az illesztés a.* részkifejezésseé addig rohan előre, ameddig csak tud. Először a füzér végéig. Itt azonban elakad, és elkezd visszafelé lépkedni. Egészen a Jangce szóig, aholis sikeres a reguláris kifejezés maradék részének az illesztése is. Ismét egy példát nézve a $_ = "Van 1 számom: 53147"; if ( /(.*)(\d*)/ ) { print "Ami van: <$1>, a szám pedig <$2>.\n"; else{ print "nincsen számom...\n"; az eredménye Ami van: <Van 1 számom: 53147>, a szám pedig <>. aminek az oka, hogy a \d* hozzáilleszthető a füzér végén egy üres füzérhez. Helyesen: $_ = "Van 1 számom: 53147"; if ( /(.*\D)(\d+)/ ) { print "Ami van: <$1>, a szám pedig <$2>.\n"; else{ print "nincsen számom...\n"; az eredménye Ami van: <Van 1 számom: >, a szám pedig <53147>. Az m operátor

A Perl programozási nyelv röviden 79/10 Az m operátor a =~ vagy!~ operátorok valamelyike által megadott füzért hasonlítja össze a reguláris kifejezéssel. A visszatérési értéke skalár környezetben =~ használata esetén true, 1 ha a reguláris kifejezés megfelel a füzérnek, illetve false, '' ha a reguláris kifejezés nem felel meg a stringnek.!~ használata esetén fordítva. Ha nem adnak meg semmilyen füzért a =~ operátorral, akkor a default $_ változót használja a Perl. Az operátor általános alakja $text =~ m{regexpgimosx ahol a gimosx karakterek bármelyike opcióként használható és az operátor működését befolyásolja a következőképpen: g globális, nem csak egyszeri keresés i kis és nagybetűk egyenértékűek m a füzért többsorosnak tekinti o a reguláris kifejezést csak egyszer értékeli ki a Perl s a füzért egysorosnak tekinti a Perl x kiterjesztett reguláris kifejezésként értelmezi a Perl a megadott reguláris kifejezést A határoló karakterek lehetnek bármilyen nem alfanumerikus, nem szóköz jellegű karakterek, ha / jelet használunk, akkor nem kell kiírni az m operátort. Ha olyan karaktert használunk határoló karakternek, amely zárójel jellegű, akkor annak párját kell használni a reguláris kifejezés lezárására. A reguláris kifejezést a Perl, mint interpolált füzért értelmezi és ha ennek kiértékelése üres füzért eredményez, akkor a legutoljára használt reguláris kifejezést használja a Perl. Ennek megfelelően a regexp tartalmazhat változókra való hivatkozást, de vigyázni kell, mert a például $/ könnyen úgy értelmezhető, mint a reguláris kifejezést lezáró per jel. Lista környezetben a visszatérési értéke egy olyan lista, amelynek elemei a kifejezésben bezárójelezett részek, például @k = "abbabaa" =~ m/(bb).+(a.)/; print $#k; print ' ',$k[0],' ',$k[1],"\n"; aminek kimenete 1 bb aa Ha nem volt sikeres a keresés, akkor üres listát ad vissza az operátor, ha pedig sikeres volt, de nem használtunk zárójeleket, akkor (1) értéket ad vissza. A opciók értelmezése hasonló, mint az s operátornál. A g opció használata esetén a nem csak egyszeri keresést több féle képpen is lehet értelmezni a környezettől függően. Lista környezetben addig keres, ameddig a füzér végére nem ér, és a bezárójelezett részeket rakja össze egy listába, például @k = "abbabaa" =~ m/(ab)(b a)/g; print $#k; print ' ',$k[0],' ',$k[1],' ',$k[2],' ',$k[3],"\n"; aminek kimenete 3 ab b ab a

A Perl programozási nyelv röviden 79/11 Skaláris környezetben a g módosító hatására minden egyes végrehajtásnál tovább keres az operátor és mindaddíg, amíg talál true értéket ad vissza, és amikor nem talál, akkor false értéket ad vissza, például $t = "abbabaa"; while( $t =~ m/(ab)(b a)/g ){ print pos($t)," $1 $2\n"; aminek kimenete 3 ab b 6 ab a Más szavakkal ilyen esetben az operátor megjegyzi, hogy hol tartott. Ezt a pozíciót egyébként a pos fügvénnyel le is lehet kérdezni. Az i opció megadása esetén a mintaillesztés során a kis és nagybetűket egyenértékűnek tekinti a nyelv. Ez alól kivételek az ékezetes magyar betűk, amelyeket a rendszer nem tekint betünek, csak akkor, ha a megfelelő POSIX setlocale fügvénnyel be lett állítva a nyelv. Az m opció esetén a füzért többsorosnak tekinti a rendszer, ami praktikusan annyit jelent, hogy minden sor végét meg lehet találni a $ jellel, ami a reguláris kifejezésben a sor vagy a füzér végét jelenti, és hasonlóan minden sor elejét a ^ jellel. Ennek az ellentéte a s opció, amely esetben a füzért egysorosnak tekinti a Perl, és a $ csak a füzér végét fogja megtalálni, vagy a füzér végén álló soremelést a ^ jel pedig csak a füzér elejét úgy, mintha sem az s sem pedig a m opciót nem adtuk volna meg. Az s opció igazi értelme, hogy ennek megadásakor a reguláris kifejezésekben a. pont karakter megfelel a soremelés karaktereknek is, míg enélkül az opció nélkül ezeknek a karaktereknek nem felel meg ez a metakarakter. Például $t = "allah\narab"; while( $t =~ /a(.)$/mg ){ print $1; print "\n"; while( $t =~ /a(.)$/sg ){ print $1; print "\n"; while( $t =~ /a(.)$/g ){ print $1; kimenete hb b b Az o opció használata esetén a reguláris kifejezést csak egyszer értékeli ki a Perl futtató rendszer a script futása során, és ha szerepel benne olyan változó, amelynek az értéke a későbbiek során megváltozik, az nem fogja érdekelni a Perl-t. Például $t = "allah arab"; $a = 'allah'; $b = 'rab'; &q;&p; $b = 'szabad'; &q;&p; sub q { print ' q',$t =~ /$a\sa$b/o sub p { print ' p',$t =~ /$a\sa$b/

A Perl programozási nyelv röviden 79/12 kimenete q1 p1 q1 p Az x opció használatakor a Perl a reguláris kifejezést kiterjesztett értelemben használja, ami azt jelenti, hogy ilyenkor a szóközöket csak akkor veszi figyelembe ha azok előtt \ karakter van. Egyébként úgy tekinti, mint olyan karakter, amely arra való, hogy olvashatóbb legyen a program. Ebben az esetben a Perl megjegyzés karakterét a # karaktert is megjegyzés kezdetének tekinti a program, így az első példánkat írhatjuk @k = "abbabaa" =~ m/(bb) #két darab 'b' bekerül $1-be.+ #egy vagy több bármilyen karakter (a.) #egy 'a' betű és pontosan egy bármilyen karakter /x; #szóköz és megjegyzés engedélyezve print $#k; print ' ',$k[0],' ',$k[1],"\n"; alakban is. Ellenőrizzük, tényleg ugyanazt írta ki: 1 bb aa Ha a reguláris kifejezésen belül zárójeleket használunk, akkor a $1, $2... változók felveszik azoknaka részfüzéreknek az értékeit, amelyek a zárójelek között vannak. Ezek a $1, $2... változók a blokk végéig, vagy a következő reguláris kifejezés kiértékeléséig használhatók. Ajánlatos minnél előbb átmásolni őket. Ugyanezekre a részfüzérekre lehet hivatkozni már a reguláris kifejezésen belül is, amennyiben valamilyen ismétlődést akarunk megkövetelni, például $t = 'aegyabkettőbcháromc' ; while( $t =~ m/(a b c)(.*)\1/g ){ print "$2 "; aminek a kimenete egy kettő három Az s operátor Az s operátor a =~ vagy!~ operátorok valamelyike által megadott füzért hasonlítja össze a reguláris kifejezéssel és az első megtalált részfüzért kicseréli a megadott helyettesítő füzérrel. Az operátor általános alakja $text =~ s{regexp{helyettegimosx ahol a egimosx karakterek bármelyike opcióként használható és az operátor működését befolyásolja a következőképpen: e a helyett értéket kifejezésként értelmezi a program g globális, nem csak egyszeri keresés i kis és nagybetűk egyenértékűek m a füzért többsorosnak tekinti o a reguláris kifejezést csak egyszer értékeli ki a Perl s a füzért egysorosnak tekinti a Perl x kiterjesztett reguláris kifejezésként értelmezi a Perl a megadott reguláris kifejezést

A Perl programozási nyelv röviden 79/13 Ha nem adnak meg semmilyen füzért a =~ vagy!~ operátorral, akkor a default $_ változót használja a Perl. A =~ vagy!~ operátorral megadott füzérnek balértéknek kell lennie, hiszen ezt a Perl módosítani akarja. A határoló karakterek lehetnek bármilyen nem alfanumerikus, nem szóköz jellegű karakterek. Ha ' karaktert használunk, akkor a Perl nem interpolált füzérként értelmezi a rguláris kifejezést illetve a helyettesítő füzért. (Kivéve ha az e opciót használjuk.) Határoló karakterként valamilyen zárójelet használva annak párját kell használni a reguláris kifejezés, vagy a helyettesítő füzér lezárására. Nem feltétlenül kell ugyanazt a karakterpárt használni a reguláris kifejezéshez és a helyettesítő füzérhez, de mind a kettőt külön be kell zárni, azaz s/alma/körte/ három határoló karaktert használ, de s(alma){korte négy határoló karaktert használ. Ha a reguláris kifejezés üres füzér, akkor a legutoljára használt reguláris kifejezést használja a Perl. Az operátor visszatérési értéke a sikeresen elvégzett cserék száma, illetve ha nem sikerült egyetlen cserét sem elvégeznie akkor false, '' üres füzér, illetve a!~ használata esetén ennek ellentéte. Precízebben ($x!~...) ugyanaz, mint (! $x =~...). A opciók értelmezése hasonló, mint az m operátornál. Az e opció esetén a program a helyettesítő füzért, mint kifejezést értékeli ki, és ennek eredményét használja a helyettesítéshez. Ez egy teljes Perl kiértékeléást jelent, úgy, mint az eval függvény használatánál, de a szintaktikus elemzés és ellenőrzés fordítási időben történik. A g opciónál a cseréket addig folytatja, amíg végig nem ér a füzéren, azaz $t = "abbab" ; $t =~ s/ab/aa/g; print $t; aminek a kimenete aabaa Ebből az is látszik, hogy a továbbkeresést onnan folytatja ahol az előző csere végetért, azaz a helyettesítésként berakott füzért már nem bántja. Ha nem használjuk a g opciót, akkor az operátor emlékszik arra, hogy hol fejezte be az előző cserét, és onnan folytatja. Ezzel lehetővé válik, hogy egy ciklussal ugyanazt a hatást érjük el, mint a g opcióval, de közben minden egyes csere után még a ciklus törzse is végrehajtódik: $t = 'bababababababab' ; $s = 'bab'; $r = 'bib'; while( $t =~ s/$s(.)/$r$1/ ){ print $1; print "\n$t\n"; aminek a kimenete aaaaaa

A Perl programozási nyelv röviden 79/14 bibibibibibibab Ha pedig a pos függvényt is bevetjük, akkor elérhetjük, hogy azokat a helyettesítő füzéreket is figyelembe veszi az operátor, amelyeket az előző csere alkalmával helyezett el a füzérben: $t = 'bababababababab' ; $T = $t; $s = 'bab'; $r = 'bib'; $T =~ s/$s/$r/g; while( $t =~ s/$s/$r/ ){ pos($t) -= length($r); print "$T\n$t\n"; aminek a kimenete bibabibabibabib bibibibibibibib Az i opció megadása esetén a mintaillesztés során a kis és nagybetűket egyenértékűnek tekinti a nyelv. Ez alól kivételek az ékezetes magyar betűk, amelyeket a rendszer nem tekint betünek, csak akkor, ha a megfelelő POSIX setlocale fügvénnyel be lett állítva a nyelv. Az m opció esetén a füzért többsorosnak tekinti a rendszer, ami praktikusan annyit jelent, hogy minden sor végét meg lehet találni a $ jellel, ami a reguláris kifejezésben a sor vagy a füzér végét jelenti, és hasonlóan minden sor elejét a ^ jellel. Ennek az ellentéte a s opció, amely esetben a füzért egysorosnak tekinti a Perl, és a $ csak a füzér végét fogja megtalálni, vagy a füzér végén álló soremelést a ^ jel pedig csak a füzér elejét úgy, mintha sem az s sem pedig a m opciót nem adtuk volna meg. Az s opció igazi értelme, hogy ennek megadásakor a reguláris kifejezésekben a. pont karakter megfelel a soremelés karaktereknek is, míg enélkül az opció nélkül ezeknek a karaktereknek nem felel meg ez a metakarakter. Példát az m operátornál mutatunk. Az o opció használata esetén a reguláris kifejezést csak egyszer értékeli ki a Perl futtató rendszer a script futása során, és ha szerepel benne olyan változó, amelynek az értéke a későbbiek során megváltozik, az nem fogja érdekelni a Perl-t. Példát az m operátornál mutatunk. Az x opció használatakor a Perl a reguláris kifejezést kiterjesztett értelemben használja, ami azt jelenti, hogy ilyenkor a szóközöket csak akkor veszi figyelembe ha azok előtt \ karakter van. Egyébként úgy tekinti, mint olyan karakter, amely arra való, hogy olvashatóbb legyen a program. Ebben az esetben a Perl megjegyzés karakterét a # karaktert is megjegyzés kezdetének tekinti a program. Példát az m operátornál mutatunk. Ha a reguláris kifejezésen belül zárójeleket használunk, akkor a $1, $2... változók felveszik azoknaka részfüzéreknek az értékeit, amelyek a zárójelek között vannak. Ezek a $1, $2... változók a blokk végéig, vagy a következő reguláris kifejezés kiértékeléséig használhatók. Ajánlatos minnél előbb átmásolni őket. Ezeket a változókat lehet használni a helyettesítő füzérben is. Ugyanezekre a részfüzérekre lehet hivatkozni már a reguláris kifejezésen belül is, amennyiben valamilyen ismétlődést akarunk megkövetelni, például $t = 'aegyabkettőbcháromc' ; $i = 1; $i++ while $t =~ s/(a b c)(.*)\1/$i/ ; print "$t\n";

A Perl programozási nyelv röviden 79/15 aminek a kimenete 123 Mutatók Perlben minden olyan változó, amely valamilyen skalár, tehát szám, fűzér stb. értéket tartalmazhat; tartalmazhat mutatót is, vagy Perl terminológiával referenciát. A Perl nyelv kétféle referenciát ismer: puha és kemény referenciát. A puha referencia a változók nevén keresztül éri el a tárolt értéket, míg a kemény referencia a változó helyére mutat. Nézzünk egy egyszerű példát: $alma = 113; $korte = 'alma'; $szilva = \$alma; print "$$korte = $$szilva\n"; És az eredményt: 113 = 113 ami egy nagy igazság. Körte egy füzért tartalmaz, és amikor a Perl értelmező a $$körte kifejezést megtalálja, akkor ebből először $alma-t csinál, majd 113-at. A $szilva változó esetében más a helyzet. Itt a $$szilva kifejezés megtalálásakor a Perl interpreter kiértékeli a $szilva változót, amely egy mutató, amely az $alma változó tartalmára mutat. Látható, hogy mind a két esetben a referencia használatához a $ jelet kellett a referencia érték elé írni. A mutató létrehozásakor a változó neve elé egy \ jelet írtunk. Nagyon kényelmes a Perl a memóriakezeléssel kapcsolatban. Nem kell mindenféle malloc, alloc és hasonló függvényeket hívnunk, és nem kell free jellegű memória felszabadító fügvényekkel sem bíbelődnünk. A Perl mindig tudja, hogy mi az amit még használunk, és mi az amit nem. Így akár azt is megtehetjük, hogy $alma = 114; sub pointir { my $alma = 113; return \$alma; $korte = 'alma'; $szilva = &pointir; print "$$korte = $$szilva\n"; egy helyi változóra mutató mutatót adunk vissza értékül (C-nél ez teljesen helytelen, és szerencsés esetben core dump a jutalom). A Perl tudja, hogy a létrehozott lokális változóra van hivatkozás és megtartja mindaddig, amíg valamilyen változón keresztül elérhető. Így az eredmény: 114 = 113 Hát ez nem igaz! Precízebben fogalmazva a lokális változót nem tartja meg a Perl, csak azt a memória helyet, ahol tárolja. Így sub pointir { my $alma = 113; return \$alma;

A Perl programozási nyelv röviden 79/16 $korte = &pointir; $szilva = &pointir; $$szilva++; print "$$korte < $$szilva\n"; eredménye 113 < 114 Persze nem csak egyszerű változókra lehet mutogatni, ennek nem is lenne sok értelme, hanem tömbökre, hash változókra, függvényekre, meg objektumokra. Nézzünk egy komplex példát, amiben van minden: $alma = sub { my @alma = (1,1,3); return \@alma; ; $dinnye = sub { my %alma = (0,1,1,1,2,3); return \%alma; ; $korte = &$alma; $szilva = &$dinnye; $$korte[2]++; $korte->[2]--; $$szilva{2++; $szilva->{2--; for $i (0.. 2){ print $$korte[$i] print ' = '; for $i (0.. 2){ print $$szilva{$i aminek eredménye 113 = 113 (Ki gondolta volna!) A példában $alma és $dinnye két függvényre mutató változó. Az egyik egy tömbre, a másik egy hash-ra mutató mutatót ad vissza értékként. Mind a kettő elérhető a már megismert módon a két $$ használatával is, de elérhetők a tömb, és a hash egyes elemei a C nyelvben megszokott -> operátorral is. Program szerkezetek A Perl az utasításokat egymás után hajtja végre, úgy mint C nyelvben. Végül is nem ez az egyetlen hasonlóság. Az utasításokat általában pontosvessző zárja le, de nem feltétlenül kell, ez elhagyható egy blokk utolsó utasításánál. Majdnem elfelejtettem. Egy program blokk, azaz utasítások egy csoportja { és között van. Ez kívülről úgy tekinthető, mint egy utasítás. Belül lehetnek utasítások, lokális változók. Viszont van if, while, do, unless. Röviden: if( kifejezés ) blokk vagy if( kifejezés ) blokk else blokk

A Perl programozási nyelv röviden 79/17 És már most érdemes észrevenni, hogy nem utasítás, hanem blokk szerepel itt is és más szerkezetekben is, azaz szintaktikusan hibás a if( $bela eq '3' ) $geza= 2 else $juli=4 szerkezet. Ehelyett a if( $bela eq '3' ){ $geza= 2 else{ $juli=4 használandó. És ez nagyon, nagyon jó. Vagy nem. Szóval attól függ, hogy a C vagy a PASCAL lelkület bújik elő belőled. Rossz, mert eszelősen sokat kell gépelni (amíg meg nem tanulod, hogy lehet utasítás if kifejezés alakban is használni), viszont baromi jó, mert nincs vele gond, hogy kell, vagy nem kell, szabad vagy nem szabad az else előtt pontosvesszőt használni, és akkor az az else most melyik if-hez tartozik? if! kifejezés helyett használható unless kifejezés. Lassulunk, pörgessük fel! Ciklusok: while( kifejezés ) blokk elején tesztel, és ami a végén tesztel: do blokk while( kifejezés ) Nincs until! Viszont van for minden mennyiségben: for( kif1 ; kif2 ; kif3 ) blokk pontosan úgy, mint C-ben, de van itt valami jobb is: for $valtozo ( lista ) blokk Ez a ciklus végigmegy a lista összes elemén, és $valtozo minden egyes ciklus lefutásra az aktuális lista elem. Erre az időre ez a változó lokális, utána ugyanaz az értéke, mint ami előtte volt. Ebbe beleértendő az is, ha az értéke undef volt. Egy ciklusból ki lehet jönni előbb is, mint ahogy az véget érne. Ha valahol a ciklus belsejében végrehajtódik egy last utasítás, akkor a ciklus befejeződik. (Hé, C programozók! Nem emlékeztet ez valami break nevü valamire?) Ha egy ciklus előtt egy cimke van, akkor a last utasításban erre lehet hivatkozni, és akkor nem feltétlenül a legbelső ciklus futása szakad csak meg, hanem a körülötte levőké is, egészen a cimkézett ciklusig. Ehhez hasonlóan létezik egy olyan utasítás, amelyik újrakezdi a ciklust. Ezt a Perl next-nek hívja. (Hopp! Hopp! Rémlik valami continue?) Természetesen itt is meg lehet adni cimkét.

A Perl programozási nyelv röviden 79/18 És most jön valami érdekes: a ciklus után meg lehet adni egy continue blokkot, amelyiket akkor végrehajtódik, ha a ciklusban egy next utasítást hajtottunk végre. Viszont van egy redo utasítás, amelyik még ezt is kikerüli, és így indítja újra a ciklust. Most már elég sokat dumáltunk, lássunk egy példát: $i = 0; while( $i < 7 ){ $i ++; print "start $i\n"; next if $i == 1; redo if $i == 2; last if $i == 4; print "end $i\n"; continue{ print "$i countinue\n"; és amit kiír: start 1 1 countinue start 2 start 3 end 3 3 countinue start 4 Biztos, hogy ezt írja ki, mert ezt a jegyzetet nem tiszta HTML-ben írom, hanem először átengedem egy (természetesen Perl-ben írt) makro preprocesszoron, amelyik többek között berakja a szövegbe a programot, meg amit kiírt azt is. Emberi hiba kizurvu. Van goto utasítás is a nyelvben. Méghozzá nem is akármilyen. Ha valaki akarja, akkor használhatja a szokásos goto CIMKE alakot, de mivel a nyelv teljesen interpretált, ezért a CIMKE helyén szerepelhet bármilyen kifejezés, amelyik egy címke nevét adja meg. (Ez például erősen megnehezíti azok dolgát, akik fordítót írnak a nyelvhez.) Ha valakinek még ez sem elegendően perverz, akkor használható a goto &NAME alak, amelyik a NAME szubrutint hívja meg, de úgy, hogy onnan már nem ide, hanem a goto utasítást tartalmazó szubrutint meghívó függvénybe tér vissza a vezérlés. (Ha még nem jutottál el odáig, akkor csak annyit, hogy a szubrutinokat a &NAME alakban kell meghívni.) Nézzünk egy goto példát: goto LABEL1; print "Ezt nem írom ki\n."; LABEL1: print "Ezt kiírom.\n"; $i = 2; goto ['LABEL00','LABEL10','LABEL20','LABEL30']->[$i]; LABEL00: print 'LABEL00'; goto ENDE; LABEL10: print 'LABEL10'; goto ENDE; LABEL20: print 'LABEL20'; goto ENDE; LABEL30: print 'LABEL30'; goto ENDE; ENDE:; &sub1; &sub2;

A Perl programozási nyelv röviden 79/19 sub sub1 { print "\nsub1\n"; goto &sub2; sub sub2 { my @c = caller(); print " @c sub2\n"; és amit kiír: Ezt kiírom. LABEL20 sub1 main gototest.pl 12 sub2 main gototest.pl 13 sub2 Szubrutinok Perl-ben nagyon egyszerű szubrutint írni: sub alma { print "Bent vagyok a szubrutinban!!!"; return; A szubrutinból kijönni a return utasítással lehet éppen úgy, mint C-ben, de ez el is hagyható. A return után lehet írni a visszatérési értéket. Ugyanúgy, mint C-ben egy szubrutinnak mindig van értéke, legfeljebb nem használjuk. Lehet, hogy jobb lenne func-nak hívni, de a Perl sub-nak hívja. Egy szubrutint úgy lehet meghívni, hogy a neve elé az & jelet írjuk. Meg lehet hívni úgy is, hogy nem írjuk oda az & jelet, de ez nem mindig működik. A függvényeknek paramétert is lehet adni. A paramétereket ugyanúgy, mint a normális programozási nyelveknél a függvényhívás után kell vesszővel elválasztva írni, zárójelek között. Ezek a @_ tömbbe kerülnek bele, és így a $_[x] formában lehet rájuk hivatkozni. &ssss(1,2,3); sub ssss { print $_[0],$_[2],$_[3],"\n"; ssss(1,2,3); A függvényeken belül hivatkozhatók a globális változók, de hivatkozhatók lokális változók is. Ezekből pedig kétféle lehet. Az egyik a függvényen belül helyileg lokális, a másik pedig időben, a függvény futási ideje alatt lokális. Nem világos? Nézzünk egy példát: $my = 'global'; $local = 'global'; &subi; &bubi; sub subi { my $my ='my'; local $local = 'local'; &bubi;

A Perl programozási nyelv röviden 79/20 sub bubi { print "$my\n$local\n"; és amit kiír: global local global global Amikor bubi először lefut $local lokális, a $my változóhoz azonban, mint globális változóhoz fér hozzá, a subi függvény $my nevü változójához nem fér hozzá. A my deklarációval létrehozott változók, tehát úgy lokálisak, mint ahogy azt megszoktuk a normális programozási nyelvek esetében, a local viszont inkább úgy viselkedik, mint aki a globális változó értékét félreteszi, majd amikor lefutott a félretett értéket visszarakja. Nézzünk most ismét egy példát: print &suba(100); sub suba { my $i = shift; if( $i%2 ){ $i+1 else{ $i-1 és amit kiír: 99 Itt két dolgot érdemes megfigyelni. Az egyik, hogy egy lokális változóba, egy shift operátorral, amelyiknek a default argumentuma a @_ tömb, kivesszük a szubrutin argumentumát. Ezzel hasonló formában lehet az argumentumokat kezelni, mint normális nyelveknél. Perlsze lehet Perlkedni, akinek kedve van, de az ember egy idő után lenyugszik, főleg ha nem csak játszik, hanem méretes programokat gyárt. A másik dolog, hogy elhagytuk a return utasítást. Egy szubrutin értéke megegyezik az utoljára végrehajtott utasítás értékével. Ha ez egy return utasítás, akkor a return után írt kifejezés értéke a visszatérési érték. Fájl kezelés A fájlkezelés az egyik legegyszerűbb dolog a Perl nyelvben. Mivel ez egy olyan terület, amelyik minden programban előfordul, és mivel a Perl elsősorban a UNIX operációs rendszerhez lett kitalálva, ahol a fájl alapfogalom, ezért nem csak könyvtári függvények, hanem programszerkezetek is rendelkezésre állnak a fájlok kezelésére. A legegyszerűbb fájlkezelő utasítás, amellyel korábbi példákban is már találkoznod kellett a print. Ez az utasítás, vagy ha úgy tetszik beépített függvény egy fájlba, vagy a szabványos kimenetre írja ki a paraméterként megadott értékeket. A paraméterek lehetnek sztringek, valós vagy egész számok, változók, amelyek ilyen értékeket tartalmaznak, de lehetnek mutatók, vagy nem skalár értékek is. Ez utóbbi esetben a print utasítás valamilyen olyan karakter alakban írja ki a változó, vagy kifejezés értékét, hogy az legalább hibakeresési célra használható legyen. Nézzünk egy egyszerű példát:

A Perl programozási nyelv röviden 79/21 $a = 1; $b= 'alma\n'; $c = "alma\n"; $d = \$c; print $a,$b,$c,$d; és az eredményt: 1alma\nalma SCALAR(0xcb7468) Látszik, hogy $a értéke 1, $b értéke az aposztróf használata miatt nem lett kifejtve, és emiatt nem újsor karakter van a végén, hanem egy \ és egy n betű, de $c végén már valóban van egy soremelés. $d egy mutató, amelyik a $c változóra mutat, és ennek nyomtatott képe a SCALAR(xxx). A konkrét érték minden egyes futtatásnál más lehet, attól függően, hogy $c hova kerül a memóriában. A print utasítás egyes paramétereit vesszőkkel választottuk el, azonban nagyon gyakran úgy akarunk kiíratni változó értékeket, hogy közbe mindenféle apróbb füzéreket helyezzük el. Például (ez a program az f2.pl fájlban van): $a=3;$b=55; print "A értéke=",$a," B értéke=",$b,"\n"; Ennek kimenete: A értéke=3 B értéke=55 Aki azonban ezt a print utasítást leírta az nagyon nem Perl fejjel gondolkozott. Az IGAZI Perl programozó ilyenkor a következő sorokat írja (ez a program az f3.pl fájlban van): $a=3;$b=55; print "A értéke=$a B értéke=$b\n"; aminek kimenete A értéke=3 B értéke=55 Ha ez nem ugyanaz, mint az előbb, akkor elrontottam a példát. (A példákat és a kiírt eredményeket a HTML fájlba egy Perl program állítja elő, így kizárt, hogy el legyen írva. Na jó: kevéssé valószínű.) Természetesen nem csak a szabványos kimenetre lehet írni, hanem bármilyen fájlba, amelyiket írásra megnyitott a program. A fájlok megnyitására az open utasítás szolgál, a fájlok bezárására pedig a close. Nézzünk egy példát: open(f,"<f2.pl"); open(g,">f3.bak"); while( $line = <F> ){ $line =~ s/",//g; $line =~ s/,"//g; print G $line; close G; close F; Ez a kis program beolvassa az egyik fenti példaprogramot, és kiírja a f3.bak fájlba azt a verziót, amelyre azt mondtuk, hogy azt egy IGAZI Perl programozó készítette. Egy kicsit lehet ebből a példából tanulni a reguláris kifejezéseket is, de most nem ez a lényeg. Figyeljünk arra, hogy hogyan nyitottuk meg a fájlt, hogyan írtunk bele, hogyan olvastunk belőle, és hogyan zártuk le.

A Perl programozási nyelv röviden 79/22 Az első dolog amit megfigyelhetünk, az az, hogy a fájlokat nem változókkal azonosítjuk, hanem handlerekkel (ki tudja a hivatalos terminológiát erre a szóra? fogantyú?). Ez azt jelenti, hogy a fájl azonosító elé nem írunk $ jelet, és általában nagybetűt szoktunk használni a fájlazonosításra a programon belül, de ez csak konvenció, nem kötelező. A másik dolog, amit meg lehet figyelni, hogy az open utasítás második argumentuma nem egyszerűen a fájl neve, hanem egy olyan füzér, amely tartalmazza a fájl nevét, de azt is, hogy a fájlt hogyan akarjuk megnyitni: írásra, olvasásra, vagy mindkettőre (ez utóbbira az előző példában nincs minta, majd még lesz). Ha az open utasításban a második argumentumban a fájl neve előtt nincsen semmilyen jel, akkor a fájlt olvasásra nyitjuk meg. Ha < jel van a fájlnév előtt, az ugyanaz, mintha nem használtunk volna semmilyen jelet. Általában szokás ezt használni, annak ellenére, hogy ez a default, mert olvashatóbbá teszi a programot. Ha a fájl neve előtt > jel van, akkor írásra nyitottuk meg a fájlt. Ha a fájl neve előtt <jel van, akkor olvasásra. Ezen kívül még használható a >> jel a fájlhoz való hozzáírásra, a +< a fájl írására és olvasására. Erre használható a +> jel is, ez azonban megnyitáskor törli a fájlt. A fájlműveletek mindig a fájl aktuális pozíciójára vonatkoznak, amelyet egy fájl foganytű (handle) tartalmaz. Amikor kiírunk valamit, akkor oda íródik a szöveg ahova a foganyú mutató mutat, és ezután a fogantyú mutató a kiírt szöveg utánra fog mutatni. Amikor beolvasunk valamit egy fájlból, akkor onnan történik az olvasás ahova a fogantyú mutató mutat, majd az olvasás után a fogntyú motató a beolvasott adatok utánra fog mutatni. Ez olyan, mint más nyelveknél. Egy fájlból olvasni a alakban lehet, ahol a kisebb és a nagyobb jelek közé kell írni a fájlkezelőt. Ez az utasítás skalár környezetben egy rekordot olvas be, lista környezetben pedig a hátralevő rekordok listáját. Egy rekord általában egy sor, mivel a rekord határoló karakter $/-ben megadva LF, de ha $/- nek más értéket adunk, akkor a beolvasás is másképp hajtódik végre. A végletekig elmenve ha a $/ változónak undef értéket adunk, akkor egész fájlokat tudunk változóba nagyon gyorsan beolvasni. Ha egy fájlon belül akarjuk mozgatni a fogantyú mutatót, akkor erre a legegyszerűbb módszer a seek függvény meghívása. Ennek formája: seek FILEFOGÓ,POZÍCIÓ,HONNAN A FILEFOGÓ a fájlkezelő, a POZÍCIÓ az a hely ahova állítani szeretnénk a mutatót, a HONNAN paraméter pedig lehet 0, 1 vagy 2. Ha HONNAN 0 akkor a fájlon belül POZÍCIÓ a fájl elejétől számít. Ha HONNAN egy, akkor a mutató pillanatnyi pozíciójához képest fog elmozdulni, ha pedig 2, akkor a fájl végétől számítva. Általában ajánlatos ezt a függvényt meghívni minden olvasási és írási művelet között. Ennek az oka nem a Perl nyelvben keresendő, hanem azokban a könyvtári függvényekben, amelyeket az operációs rendszer biztosít a Perl programok számára. A seek meghívásának a hatására a kiírandó adatok kikerülnek a pufferből, míg egy olvasás utáni írásnál egyes operációs rendszereken nem. Ha azt akarjuk megtudni, hogy a fájlfogantyú mutatója éppen hova mutat, akkor a tell függvényt hívhatjuk meg. Argumentuma a fájlfogantyú, ha nem adunk meg argumentumot, akkor az utoljára olvasott fájlt fogja használni. Egy fájl hosszát le lehet rövidíteni a truncate függvénnyel. Ennek két argumentuma van: a fájlfogantyú, és a megkívánt hossz. Amikor egy fájlba írunk, vagy olvasunk onnan, akkor előfordulhat, hogy más is hozzá akar férni a fájlhoz. Ez pedig gondot okozhat, ha egyszerre több processz is ír a fájlba. Ha tehát egy fájlt le akarunk foglalni, akkor a flock függvényt kell használni. Ennek két argumentumot kell megadni. Az első a fájlfogantyú, a másodika lezárás módja: