Sarrera

Blog honetan, “Testu-analisirako PERL erremintak” liburuko (UEU 2009) kasu praktikoak jarri ditugu. Liburuaren asmoa, konputagailu bidez testuak aztertu eta manipulatu nahi dituztenei abiapuntua eskaintzea da, horretarako PERL programazio-lengoaia erabiliz norberaren neurri eta beharretara egokitzen diren programak garatzeko.
Kasu praktiko edo ariketa esanguratsuenak sarean jarri nahi izan ditugu,nahi duen orok jeitsi, probatu, aldatu… ditzan. Noski, gustura jasoko genituzke zuen iruzkin eta programak ere.

Zer behar dut Perl lengoaian programatzen hasteko?

Hiru oinarrizko tresna erabiliko ditugu etengabe programatzerakoan:

  • Perl interpretatzailea: Linux erabiltzailea bazara ez duzu instalatu beharrik  izango, banaketa gehienek berekin baitaramate Perl interpretatzailea. Aldiz, Windows erabiltzen baduzu, ActivePerl instalatzea gomendatzen dizugu. Jeisteko, sakatu hemen.
  • Testu-editorea: Programak idazteko erabiliko dugun tresna da testu-editorea. Linux erabiltzaileak bagara, emacs, gedit edo kedit erabili dezakegu. Windows zaleek Notepad edo Wordpad testu-editoreak dituzte eskura, baina programazio-lana asko errraztuko digu Notepad++ bezalako testu-editoreak. Jeisteko, sakatu hemen.
  • Komando-lerroa: programak abiarazi eta emaitzak pantailaz ikusi ahal izateko. Komando-lerroaren leihoa zabaltzeko, Windows-en Hasi–>Exekutatu eta zabaltzen den lehioan idatzi cmd. Linux-en programa hauetakoren topatu eta abiatu; terminala, terminal, xterm, konsole…

Programatzerakoan, bi pausoko prozesua jarraituko dugu:

  1. Edizioa: testu-editorearekin (emacs, Notepad++) fitxategi bat zabaldu eta Perl lengoaiako aginduak erabiliz programa idatzi.
  2. Exekuzioa: Komando-lerrotik Perl interpretatzaileari dei egin programa exekutatu dezan.

Eskuineko zutabean ariketa mordoa daukazu praktikatzeko. Ariketa bakoitzerako hiru atal aurkituko dituzu: enuntziatua, erabilera-adibidea eta kodea.
Lehenbiziko Adierazpen erregularrak ataleko ariketekin ahalegindu, eta gero hortik egin salto beste ataletara.
Zenbait ariketatan testu-fitxategi lagungarri batzuk erabiltzen dira (egunkarietako testuak, hiztegi-definizioak…) UEUko Otarretik jaitsi ditzakezu.
Proba egin beldurrik gabe, hemen ere, arituz ikasten baita.

Koldo Gojenola, Aitor Soroa, Aitzol Astigarraga eta Kepa Sarasola

11. kasu praktikoa: bilaketak testuan

      Testu-editore guztiek izan ohi duten Bilatu funtzioa inplementatuko dugu Perl erabiliz: programak regExpOrok.pl izena izango du, eta komando-lerrotik fitxategi-izena eta bilaketa-patroia jaso, eta patroia betetzen duten lerroak bistaratuko ditu pantailan. Letra larrien eta xeheen arteko bereizketarik ez du egin behar programak.
      Adibidez, esaeraLabur.txt fitxategian beti hitza daukaten esaeren bila bagabiltza:

>perl regExpOrok.pl esaeraLabur.txt beti
Beti on nahi duena, maiz gaizki
Nagia, beti lantsu
>

Hona programa:

regExpOrok.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 open(FITX, $ARGV[0]) or
      die(“Ezin $ARGV[0] fitxategia irekin”);
 my $patroia = $ARGV[1];
 my $lerroa;
 while ($lerroa = <FITX>) {
      print ($lerroa) if ($lerroa =~ m/$patroia/i);
 }
 close(FITX);

Jaitsi   regExpOrok.pl   fitxategia

12. kasu praktikoa: perltsolaritza

      Lagun baten ezkontza-ospakizuna dela-eta, bertso bat idaztea egokitu zaigu. Jarri gara lanean, eta bueltak eta bueltak eman ondoren, sekula aurretik inori bururatu gabeko (ejem) bukaera etorri zaigu burura: «elkarrekin zoriontsu/bizi izan zaiteztela». Orain gainerako puntuak osatu behar. Ekin diogu lanari, baina puf, ez da uste bezain erraza, errimak falta zaizkigu bertsoa osatzeko… Eskerrak Perl
badakigun! Bat-batean otu zaigu fitxategi bat eta hitz-bukaera emanda, bukaera berdineko hitzak topatzea oso erraza dela!
      Programa badaukagu, regExpOrok.pl , fitxategia behar dugu orain. Edozeinek balio dezakeen arren, gure lanerako egokiena xuxen.txt fitxategia da, 80.000 hitz baino gehiago dauzkan hiztegia, bakoitza lerro banatan.
      Hauxe litzateke ela bukaerarekin errimatzen duten hitzak topatzeko modua (oharra: b karaktere bereziak hitzaren bukaera adierazi nahi du, hau da, hitzaren barrukoa ez dena. Honek zuriunea, puntua, koma, … adierazten du):

>perl regExpOrok.pl xuxen.txt “elab”
Adela
adela
aharkela
akuarela
albagela
aldagela

zoazkiotela
zoaztela
>

     Holako errima-erauntsirik! Ez dira pantailan sartu ere egiten. Irteera fitxategi batera birbideratzea ideia ona litzateke, ondoren fitxategia editatu eta errimak lasai begiratzeko:
 
>perl regExpOrok.pl xuxen.txt “elab” > ela.txt
 >

     Tira, ezin izango esan dugu behintzat errima faltagatik utzi dugunik bertsoa osatu gabe!


13. kasu praktikoa: gurutzegramak

      Ona omen da garunari herdoila kentzeko gurutzegramak egitea. Gurea gogortu xamarra dago honezkero, nahiz eta gogotsu hasi, nekez amaitu ohi ditugu eta. Bukaera aldera beti gelditzen zaigu asmatu ezineko baten bat. Ez aurrera eta ez atzera, holakoetan etxeko ohiko hiztegiek apenas laguntzen diguten.
     Nola bilatu hiztegian, adibidez, lehenengo letra “e” eta azkena “o” daukaten 3 letrako hitzak? Edo “ia” kateaz amaitzen diren 5 karaktereko hitzak? Era honetako bilaketak egiteko hiztegi elektronikoa beharko genuke, eta bilaketak zehazteko lengoaia egokia ere bai.
     Ez daukagu urrutira joan beharrik. Hiztegi elektronikoa eskura daukagu,
xuxen.txt, eta zer hoberik adierazpen erregularrak baino bilaketa-terminoak zehazteko?
     Herdoildutako kaskoari buelta batzuk eman, eta onena neurrira egindako Perl programa idaztea litzatekeela erabaki dugu, programaren sarrera/irteera honela zehaztuz: sarrerako datu gisa bi argumentu, lehena hiztegi-fitxategiaren izena, eta bigarrena bilaketa-terminoa edo -patroia. Irteera, bilaketa-patroiarekin bat egiten
duten hiztegiko hitzen zerrenda izango da.
     Programaren gakoa bilaketa-patroian dago. Nola adierazi gure murriztapenak? Hona modu bat: karaktere ezagunak bere horretan idatzi eta ezezagunak puntu karaktere bidez adierazi. Adibidez: 6 karaktereko hitza “ra” katearekin bukaeran, “….ra”. Edo, “e” letraz hasi eta “a” letraz amaitzen den 4 karaktereko hitza, “e..a”. Puntu karakterea ez dugu besterik gabe aukeratu karaktere ezezagunak adierazteko, ezta? Ez, noski, puntu karakterea berezia da adierazpen
erregularretan, “edozein karaktere” adierazten duen metakarakterea.
Horretxegatik aukeratu dugu hain zuzen ere karaktere ezezagunak adierazteko.

Algoritmoa:
1. Komando-lerrotik jasotako fitxategia ireki
2. Teklatu bidez bilaketa-terminoa jaso, $bilaketa
3. Fitxategiaren $lerro lerro bakoitzeko
      3.1. Baldin ($lerro =~ /^$bilaketa$/i) orduan
            bistaratu $lerro
4. Fitxategia itxi

Programa:
gurutzegramak.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 print(“Idatzi bilaketarako terminoa: “);
 my $bilaketa = <STDIN>;
 chomp($bilaketa);
 open(FITX, $ARGV[0]) or
      die(“Ezin $ARGV[0] fitxategia ireki!n”);
 my $lerro;
 while ($lerro = <FITX>) {
      # patroiak osorik bat egin behar du $lerro-ko
      # edukiarekin
      if ($lerro =~ /^$bilaketa$/i) {
                 print(“$lerro”);
      }
 }
 close(FITX);

Jaitsi   gurutzegramak.pl   fitxategia

Hobekuntza: exekuzio aldi bakoitzean nahi adina bilaketa burutzen dituen programa (“q” letra sakatu artean iteratzen jarraituko du).

gurutzegramak2.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 print(“Idatzi bilaketarako terminoa. Amaitzeko, idatzi qn”);
 my $bilaketa = <STDIN>;
 chomp($bilaketa);
 open(FITX, $ARGV[0]) or
      die(“Ezin $ARGV[0] fitxategia ireki!n”);
 my $lerro;
 while ($bilaketa ne “q”) {
       while ($lerro = <FITX>) {
              # patroiak osorik bat egin behar du $lerro-ko
              # edukiarekin
               if ($lerro =~ /^$bilaketa$/i) {
                     print(“$lerro”);
               }
       }       # amaitu da bilaketa
       # fitxategiaren hasierara mugitu
       seek(FITX, 0, 0);
       print(“nnIdatzi bilaketarako terminoa. Amaitzeko,
              idatzi qn”);
       $bilaketa = <STDIN>;
       chomp($bilaketa);
 }
 close(FITX);

Jaitsi   gurutzegramak2.pl   fitxategia

14. kasu praktikoa: hitz-egiturak

      Egitura konkretuko hitzak bilatuko dituen programa eskatu digute esperimentu linguistiko baterako. Adibidez: K B K B idatziz gero, Kontsonantea-Bokala-Kontsonantea-Bokala egitura duten hitzak bilatu beharko lituzke programak: pala, sute, pila, etab.
      Sarrerako datu gisa, hitz-egitura eta bilaketa-fitxategia behar ditugu, horiek programan jasotzeko bi bide ezberdin erabiliko ditugularik: patroiaren egitura komando-lerroaren bitartez, letra larriz eta letren artean hutsune bat utziz, modu honetan: B K B (Bokala-Kontsonantea-Bokala). Bilaketa-fitxategia, berriz, programak berak eskatuko du abiatzean.
      Programaren dei posible bat hauxe litzateke:

>perl egitura.pl K B K K B
Zein fitxategitan egingo dut bilaketa?
xuxen.txt
bable
bafle
balbe

zurtu
Zutza
zuzki
>

Programak bi egiteko nagusi dauzka:
1. Komando-lerrotik jasotako egiturarekin bilaketa-patroia eraiki.
2. Sarrera estandarretik jasotako fitxategian bilaketak egin.

Algoritmoa:
1. Komando-lerrotik jasotako egiturarekin patroia eraiki
     1.1. Jasotako $arg argumentu bakoitzeko
           1.1.1. Baldin $arg berdin “K” orduan
                    $patroia patroiari kontsonantea gehitu
           1.1.2. Bestela, baldin $arg berdin “B” orduan
                    $patroia patroiari bokala gehitu
           1.1.2. Bestela bistaratu “argumentu okerra”
2. Sarrera estandarretik jasotako fitxategian bilaketak egin
     2.1. Teklatutik jasotako fitxategia ireki
     2.2. Fitxategiaren $lerro lerro bakoitzeko
           2.2.1. Baldin ($lerro =~ /$patroia/i) orduan
                bistaratu $lerro
     2.3. Fitxategia itxi

Programa:

egitura.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 my $konts = “[bcdfghjklmnñpqrstvwxz]”;     # kontsonanteak
 my $bok = “[aeiou]”;                       # bokalak
 my $patroia = “b”;    # hasieratu patroia hitz-mugarekin
 foreach my $arg (@ARGV) {
      if ($arg eq “B”) {
                 # kateatu bokala patroiari
                 $patroia = $patroia . $bok;
      }
      elsif ($arg eq “K”) {
                 # kateatu kontsonantea patroiari
                 $patroia = $patroia . $konts;
      }
      else {
                 die(“Patroi egitura okerran”);
      }
 }
 $patroia = $patroia . “b”;   # hitz-muga kateatu bukaeran
 print(“Zein fitxategitan egingo dut bilaketa?n”);
 my $fitx = <STDIN>;
 open(FITX, $fitx) or
      die(“Ezin $fitx fitxategia zabaldu!n”);
 my $lerroa;
 while ($lerroa = <FITX>) {
      # i modifikatzailea: letra larri/xehe bereizketarik ez
      if ($lerroa =~ /$patroia/i) {
             # bat egiten duen string puska soilik bistaratu
             print(“$&n”);
       }
 }
 close(FITX);

Jaitsi   egitura.pl   fitxategia

15. kasu praktikoa: nola hasi hala amaitu

Karaktere berdinarekin hasi eta amaitzen diren lerroak topatzen dituen programa da honakoa.

hasiBuka.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 my $fitx = $ARGV[0];
 my $lerro,
 open(FITX, $fitx) or
      die(“Ezin izan dut $fitx fitxategia zabaldu!n”);
 while ($lerro = <FITX>) {
      chomp($lerro);
      if ($lerro =~ /^(.).*1$|^.$/) {
            # karaktere bakarreko kasua ere aintzat
            print (“$lerron”);
            }
 }

Jaitsi   hasiBuka.pl   fitxategia

16. kasu praktikoa: N. bat-egitea aurkitu

Bilaketa programa bat garatuko dugu, patroi bat eman eta haren N. agerpena edo bat-egitea topatzen duena.
Sarrera gisa, komando-lerrotik fitxategi-izena, bilaketa-patroia eta N zenbaki bat jaso eta irteera, patroiaren N. agerpena eragin duen lerroa izango da. Hona adibide gisa, esaeraLabur.txt fitxategian “ez” patroiaren 2. agerpena bilatzen duen programa deia:

>perl agerpenN.pl esaeraLabur.txt ez 2
topatu dut!
Bat eman eta bi hartu, gure etxean ez berriz sartu

Hona programa:

agerpenN.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 my $fitx = $ARGV[0];
 my $patroi = $ARGV[1];
 my $zenb = $ARGV[2];
 my $kop = 0;
 my $lerro,
 open(FITX, “$fitx”) ||
      die(“Ezin $fitx fitxategia zabaldu!n”);
 while ($lerro = <FITX>) {
      while ($lerro =~ /$patroi/gi) {
            $kop++;
            if ($kop == $zenb) {
                 print (“topatu dut!n”);
                 print ($lerro);
            }
      }
 }

Jaitsi   agerpenN.pl   fitxategia

17. kasu praktikoa: esku bakarrarekin idatzitako hitzak

     Jolaserako tartea ere hartu behar da noizean behin, dena ez da izango azalpena eta ariketa. Hona hemen, jolasa eta ariketa uztartzen dituen proposamen bat: gure ordenagailuetako ohiko teklatua erabiliz (QWERTY), eta mekanografiako
arauak aplikatuz, zein da esku bakarra erabiliz idatz dezakezun hitzik luzeena?
     Nahasmenik izan ez dadin, hauek dira mekanografiako arauen arabera ezkerreko eskuarekin idatz daitezkeen karaktereak: q w e r t a s d f g z x c v b. Hitzak: zerbeza, baztertze, area. Eskuineko eskuari dagozkionak, aldiz: y u i o p h j k l ñ n m. Hitzak: mihi, ukuilu.
    Ea nork topatzen duen luzeena. Gurea “berraztertze” da, 12 karakterekoa.
    Laguntza gisa, Perl script bat idatz dezakezue, teklatu bidez hitz bat jaso eta ezkerreko eskuaz, eskuinez edo biak erabilita idatzi dugun esango diguna.

Hona ataza hori burutzen duen programa:

qwerty.pl
 #!/usr/bin/perl
 # Sarrera: teklatu bidez idatzitako hitza
 # Irteera: ezkerreko eskuaz, eskubikoaz edo biak
 # erabilita idatzi den
 use warnings;
 use strict;
 print(“Idatzi hitz bat eta ondoren sakatu returnn”);
 my $lerro = <STDIN>;
 chomp($lerro);
 my $luzera = length($lerro);
 # ezkerreko eskuarekin soilik?
 if ($lerro =~ /^[qwertasdfgzxcvb]+$/i) {
      print(“Ezkerraz idatzitakoa. Luzera: $luzeran”);
 }
 # eskubiko eskuarekin soilik?
 elsif ($lerro =~ /^[yuiophjklñnm]+$/i) {
      print(“Eskubiaz idatzitakoa. Luzera: $luzeran”);
 }
 else {
      print(“Bi eskuak erabili dituzu!”);
 }

Jaitsi   qwerty.pl   fitxategia

     Topatu al duzu gurea baino hitz luzeagorik? Ea bada, oraingoan gu geu hitzak asmatzen aritu beharrean, sarrera gisa fitxategi bat pasatuko diogu programari eta berak bistaratu ditzala ezkerreko zein eskuineko eskuekin idatzitakoak. Baita alde bakoitzeko hitzik luzeenak ere.
     Programa hau ez da aurrekoa bezala di-da batean idaztekoa, eta komeni da aurretik algoritmoa ondo zehaztea:
1. Fitxategia ireki
2. Fitxategi amaiera ez den bitartean, irakurri $lerro
      2.1. $lerro string-ean aurkitzen duen hitz bakoitzeko
             2.1.1. Gorde hitza $hitza aldagaian
             2.1.1. Kalkulatu karaktere kopurua eta gorde:
                      $karKop = length($hitza);
             2.1.2. Baldin $hitza ezkerraz idatzitakoa, bistaratu mezua
                     2.1.2.1. Hitzik luzeena da?
                          if ($karKop > $ezkerLuze) orduan
                                   $ezkerLuze= $karKop;
                                   $ezkerHitz = $hitza;
             2.1.3. Bestela, baldin $hitza eskubiaz idatzia, bistaratu mezua
                     2.1.3.1. Hitzik luzeena da?
                          if ($karKop > $eskuinLuze) orduan
                                   $eskuinLuze = $karKop;
                                   $eskuinHitz = $hitza;
3. Bistaratu $ezkerHitz, $ezkerLuze eta $eskuinHitz, $eskuinLuze

Programa:

qwerty2.pl
 #!/usr/bin/perl
 # Sarrera: komando lerrotik fitxategi-izena
 # Irteera: bistaratu ezkerreko edo eskubiko eskuaz soilik
 # idatzitako hitzak, # eta hitzik luzeenak
 use warnings;
 use strict;
 open(Fitx, $ARGV[0]) ||
      die(“Ezin izan dut $ARGV[0]
 fitxategia zabaldu!n”);
 my $lerro;
 my $hitza;
 my $karKop;
 my $ezkerLuze = 0;
 my $eskuinLuze = 0;
 my $ezkerHitz;
 my $eskuinHitz;
 while($lerro = <Fitx>) {
      chomp($lerro);
      # baldintza: lerroko hitz bakoitzeko
      while ($lerro=~/(w+)/g){
                 $hitza = $1;   #hitza gorde
                 $karKop = length($hitza);
                 # ezkerrarekin?
                 if ($hitza =~/^[qwertasdfgzxcvb]+$/i) {
                      print(“Ezkerraz:t$hitzan”);
                      # ezkerraz idatzitako luzeena?
                      if ($karKop > $ezkerLuze) {
                        $ezkerLuze= $karKop;
                        $ezkerHitz = $hitza;
                      }
                 }
                 # eskuinarekin?
                 if ($hitza =~/^[yuiophjklñnm]+$/i) {
                      print(“Eskubiaz:t$hitzan”);
                      # eskuinaz idatzitako luzeena?
                      if ($karKop > $eskuinLuze) {
                        $eskuinLuze = $karKop;
                        $eskuinHitz = $hitza;
                      }
                 }
      }
 }
 print (“Ezkerraz idatzitako luzeena: $ezkerHitz.
         Karaktereak: $ezkerLuzen”);
 print (“Eskuinaz idatzitako luzeena: $eskuinHitz.
         Karaktereak: $eskuinLuzen”);

Jaitsi   qwerty2.pl   fitxategia

18. kasu praktikoa: bilatu eta ordeztu

     Testu-editoreetan horren erabilia den bilatu eta ordeztu funtzioa inplementatuko dugu adierazpen erregularrak erabiliz. Programak sarrerako hiru argumentu izango ditu ondoko programa-deiak erakusten duen bezala:

  >perl ordezkatu.pl esaeraLabur.txt kaixo iepa

     Programak, esaeraLabur.txt fitxategiko kaixo hitzaren agerpen guztiak ordezkatuko ditu iepa hitzarekin. Horrekin batera, egindako ordezkapen kopurua pantailaratu behar du baita.

ordezkatu.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 # Egiaztatu argumentu kopurua egokia dela
 die(“programak hiru argumentu behar ditu!n”)
      if ($#ARGV != 2);
 open (FITX, $ARGV[0]) ||
      die(“Ezin $ARGV[0] fitxategia zabaldun”);
 my $lerro;
 my $agerpenak;
 while ($lerro = <FITX>) {
       $agerpenak += ($lerro =~ s/$ARGV[1]/$ARGV[2]/ig);
       print $lerro;
 }
 print (“nnOrdezkapen kopurua: $agerpenakn”);

    Programak lerroz lerro irakurtzen du fitxategia ohiko egitura erabiliz. Lerro bakoitzean, ordezkapenak egin eta zenbatzen dituen sententzia hauxe da:
$agerpenak += ($lerro =~ s/$ARGV[1]/$ARGV[2]/ig);

      Idatzi dugun programa, ohiko bilatu eta ordeztu funtzioa baino askoz ahaltsuagoa da, adierazpen erregularrak onartzen baititu bilaketa-patroi gisa. Demagun, adibide bat jartzearren, fitxategi bateko bokal guztiak ordezkatu nahi ditugula “*” jarriz euren lekuan:

 >perl ordezkatu.pl esaeraLabur.txt [aeiou] *
 *d*sk*d*g*b*k* b*z*tz*, **z*g*b*k* h*r**tz*.
 *ld* l*z**k, g*zt** *h*zt*
 …
 Z*h*rr*r* *z *sk* g*r*
 Ordezkapen kopurua: 833
 >

Jaitsi   ordezkatu.pl   fitxategia

19. kasu praktikoa: lehen eta azken hitzak trukatu

     Teklatu bidez esaldi bat jaso, eta esaldiko lehen eta azken hitzak trukatzen dituen programa da honakoa.

trukatu.pl
 #!/usr/bin/perl
 use warnings;
 use strict;
 my $esaldia;
 print(“Idatzi esaldi bat eta sakatu returnn”);
 $esaldia = <STDIN>;
 $esaldia =~ s/^(w+)(.*)b(w+)$/$3$2$1/;
 print $esaldia;

Jaitsi   trukatu.pl   fitxategia