İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır

Pattern (string / kelime ) Örneği Bulma:(Pattern Matching)

Giriş

Bilhassa dosyalarda tarama yaparken çok kullanılan bu işlemin kurallarını öğreneceğiz.

Pattern nedir ? : slash (/) karakterleri arasında bulunan karakter dizisidir.

Ör: /gazi/ Bu pattern gazi kelimesini temsil eder. Pattern tarandığı bir satırda bulunduğunda uygun örnek bulunmuş olur. Biz şu ana kadar pattern bulma ile ilgili olarak @array = split(/ /, $line); benzeri örnekler gördük. Burada / / boşluk karakterini temsil ediyor ve o amaçla aranıyordu.

Pattern bulmada kullanılan operatörler:

Bir karakter stringinde pattern parçası bulmak için özel operatörler vardır. patternin varlığını test eden operatör =~ operatörüdür.Ör:

$sonuc = $degisken =~ /abc/;

Bu komutla $degisken içinde(stringte) abc patterninin bulunduğu test edilir. Sonuç $sonuç değişkenine atanır. Sonuç ise aşağıdakilerden biridir:

!~ operatorü, =~, operatörüne benzer tek farkla ki bu operatör patternin bulunmadığını (olumsuz karşılaştırma) test eder. Ör:

$sonuc = $degisken !~ /abc/;

Burada abc bulunmuşsa $sonuc değeri 0 dır.Bu tip kodlamalar özellikle şart ifadelerinde çok kullanılır. Örnek program : Program adı pat1.pl

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

 print ("Icinde Lutfen kelimesi olan bir soru cümlesi giriniz:\n");

 $soruyual = ;

 if ($soruyual =~ /lutfen/) {

     print ("Istenilen kelimeyi girdiniz.Teşekkür ederim!!\n");

  } else {

     print ("Istenilen kelimeyi neden girmediniz?.\n");

  }

Çalışması:

>pat1.pl

    Icinde Lutfen kelimesi olan bir soru cümlesi giriniz:

    Lutfen kapıyı açarmısınız?

    Istenilen kelimeyi girdiniz.Teşekkür ederim!
>

PATTERNLERDE ÖZEL KARAKTERLER

+ KARAKTERLERİ KULLANIMI

önündeki(sol) karakterden 1 veya fazlası anlamındadır. ör: /de+f/ patterni aşağıdakilerinden herhangi birini bulur .

    def

    deef

    deeef

    deeeeeeef

+ karakteri mumkun olduğunca önündeki karakterden 1 den fazla olanı bulur.

Ör : /ab+/ ,abbc stringini taradığında, bulduğu örnek abb dir ab değil. + kullanımı özellikle bir satırı kelimelere bölme gibi işlemlerde çok kullanışlıdır. Örneğin bir satırda kelime aralarında bir veya birden fazla boşluk varsa ve bu boşluklardan kelime ayırımı yapacaksak + karakteri kullanımı çok uygundur.

Ör : Girilen satırdaki kelimeleri sayan program yazalım. Satır girişi anında kelime aralarında 1 den fazla da boşluk bırakarak sonucu görelim. Program adı pat2.pl olsun.

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

 $kelimesayisi = 0;

 $satir = <STDIN>;

 while ($satir ne "") {

       chop ($satir);

       @kelimeler = split(/ +/, $satir);

       $kelimesayisi += @kelimeler;

       $satir = <STDIN>;

 }

 print ("Toplam kelime sayısı: $kelimesayisi\n");

Çalışması:

>pat2.pl

    Bu bir satır.

    Bu   başka   bir    satır.

    Bu da        son satır       olsun.

    ^D

    Toplam kelime sayısı: 12

>

[] KARAKTERİ KULLANIMI

Bu karakter bir alternatif gruptan bir karakteri tanımlamak için kullanılır. Ör: /d[aA]f/ patterni daf ve dAf örneklerini bulur. Bu kullanımda pattern içeriği daha fazla da olabilir. Ör:/a[0123456789]e/ gibi..

Bu pattern a ile başlayan,onu takip eden bir rakam ve son karakter olarak e ile sonlanan örnekleri bulur. Daha evvel öğrendiğimiz + karakterini de [] karakteri ile birlikte kullanabiliriz. Ör: /a[cC]+f/ Bu pattern a ile başlayan,son karakteri f olan ve arada da bir veya birden fazla c ve C karakterleri olan örnekleri bulur.

					acf

       aCf

        accf

        aCcf

        aCcCcf

Örnek Program : Adı pat3.pl. Önceki programda boşluk ve tab karakterini de düzenleyecek bir uygulama (kelimeler arsında bir veya fazla boşluk ve tab kullanılabilir).

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

$kelimesayisi = 0;

 $satir = <STDIN>;

 while ($satir ne "") {

       chop ($satir);

       @kelimeler = split(/[\t ]+/, $satir);

       $kelimesayisi += @kelimeler;

       $satir = <STDIN>;

 }

 print ("Toplam kelime sayısı: $kelimesayisi\n");

Çalışması:

>pat3.pl

    Bu bir satır.

    Bu  başka bir satır.

   Bu da        son satır       olsun.
    
			^D
		
		Toplam kelime sayısı: 12
>

Bu örnekte bir öncekinden tek bir fark vardır split(/[\t ]+/, $satir); kodlaması. Bu kodlama ile $satir değişkeninde bulunan ekrandan girdiğimiz satırda eğer kelimeler arasında bir veya birden fazla boşluk veya tab varsa bunların tümünü kelime ayıraç karakteri say ve öyle değerlendir komutu vermiş oluyoruz.

* KARAKTERİ KULLANIMI

* karakteri önündeki karakterden bir veya fazla olduğunda veya hiç olmadığında geçerli örneği bulur. Örneğin, /de*f/ paterni aşağıdaki örnekleri elde eder

df (ilk karakter -d-, son karakter -f-,arada -e- yok)

def (ilk karakter -d-, son karakter -f-,arada 1 tane -e- var)

deef (ilk karakter -d-, son karakter -f-,arada 1 den fazla -e- var)

 v.b... 

Bu karakter,[] karakteriylede kullanılır. Ör:/[eE]*/ gibi ..Bu pattern ile boş string ve e ile E karakterleri karışımı örnekler elde edilir.

? KARAKTERİ KULLANIMI

? karakteri önündeki karakterden bir tane veya hiç olmadığında geçerli örneği bulur. Örneğin patternimiz şu ise, /de?f/ bu patternin elde edeceği örnekler, df ve def tir.Dikkat ediniz deef,uygun örnek değildir çünkü, ? karakteri 1 taneden fazla karakteri kabul etmez.

BU TİP ÖZEL KARAKTERLER İÇİN ESCAPE DİZİSİ KULLANIMI

Perlde bulunan ve işlevi olan bazı karakterler ($,^,\, ..v.b.) pattern içinde nasıl kullanılır? Görelim. Bu karakterleri kendi özellikleriyle kullanmak için pattern içinde önlerine bir \ karakteri konur veya \Q \E karakterleri arasında kullanılır. mesela /\\+/ patterni stringte tüm \ karakteri (1 veya daha fazla) örneği olup olmadığını test eder. /\$/ $ karakterini, /\Q^ab*/ patterni, ^ab* karakterlerini, /\Q^ab\E*/ patterni ise,^a ile bunu takiben b karakterini test eder.(yani ^a dan sonra b olan ve b olmayanlar(* dan dolayı-hatırlayınız- doğru örneklerdir).

HERHANGİBİR KARAKTER VE SAYI ÖRNEĞİ BULMA

/a[0123456789]c/

Bu pattern ilk karakteri a son karakteri c olan ve aralarındaki karakterde 0 ile 9 arası herhangi bir rakam olan örnekleri test eder.Bu pattern daha kısa olarak şöyle de yazılabilir;

/a[0-9]c/

aynı işlevi görürler. Örneğin a1c,a5c,a9c doğru örneklerdir. Benzer şekilde ( 0-9 kullanımı) küçük ve büyük harflerde test edilebilirler. Ör:

/[a-z][A-Z]/, /[A-Z][A-Z]/, /[a-z][a-z]/, gibi..

ve rakam ve harfler birarada da test edilebilirler. Ör:

/[0-9a-zA-Z]/  gibi..([] arasındaki karakterlerden birisi varsa geçerlidir)

Örnek program : Basit bir değişken adı sınama programı. Program adı pat4.pl olsun.

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

 print ("Bir değişken adı giriniz:\n");

 $degisken = <STDIN>;

 chop ($degisken);

 if ($degisken =~ /\$[A-Za-z][_0-9a-zA-Z]*/) # skalar değişken olması için
                                                                
                                                                # $ karakteri ile başlamalı,herhangi 


                                            # bir harf ve _ karakteri veya 


                                            # herhangibir harf veya rakam olmalı

       {

    print ("$degisken bir skalar değişkendir\n");

} elsif ($degisken =~ /@[A-Za-z][_0-9a-zA-Z]*/)# dizi değişkeni olması için
                                                                # @ karakteri ile başlamalı,herhangi 

                                                 # bir harf ve _ karakteri veya 

                                                 # herhangibir harf veya rakam olmalı

       {

       print ("$degisken bir dizi değişkenidir\n");

} elsif ($degisken =~ /[A-Za-z][_0-9a-zA-Z]*/)  # dosya değişkeni olması için
                                                                    
                                                                    # herhangi bir harf ile başlamalı, 

                                                # sonra _ karakteri veya 

                                                # herhangibir harf veya rakam olmalı

        {

         print ("$degisken bir dosya değişkenidir\n");

 # Bu aşamada herhangibir değişken adı kuralına uymuyor demektir.

 } else {

        print (" $degisken değişken adı kurallarına uymuyor.\n");

 }

Çalışması :

>pat4.pl

    Bir değişken adı giriniz:

    $soyad

    $soyad bir skalar değişkendir

>

TAM ÖRNEĞİ BULMA

Yukardaki programda değişken adı olarak aşağıdakilerden

$soyad

ad$soyad

$soyad#atla

sonuçta /\$[a-zA-Z][_0-9a-zA-Z]*/ patterni $soyad'ı bulacaktır. Dolayısıyla istediğimizin tam gerçekleşmemiş olur. Çünkü doğru örnek sadece 1.si ($soyad) olmalıydı.Tam olarak $soyad'ı bulsun istersek;yani sadece bu örnekte değil genelde tam örnek bulunsun istersek;tam örnek bulma (Pattern Anchoring) karakterleri kullanırız. Bunlar;

karakterleridir.

Şimdi örneklerle daha iyi anlayacağız.

Şimdi önceki programa (pat4.pl) daha iyi bir değişken adı test programı yazabiliriz.

Göster Gizle Kopar Satır Gizle Satır Göster
Program adı pat5.pl olsun.

#!/usr/local/bin/perl

 print ("Bir değişken adı giriniz:\n");

 $degisken = <STDIN>;

 chop ($degisken);

 if ($degisken =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/) {

          print ("$degisken bir skalar değişkendir\n");

 } elsif ($degisken =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) {

         print ("$degisken bir dizi değişkenidir\n");

 } elsif ($degisken =~ /^[A-Za-z][_0-9a-zA-Z]*$/) {

         print ("$degisken bir dosya değişkenidir\n");

 } else {

        print ("$degisken değişken adı kurallarına uymuyor.\n");

 }

Çalışması:

>pat5.pl

    Bir değişken adı giriniz:

    5$soyad

    5$soyad değişken adı kurallarına uymuyor.
>

KELİME SINIRLARINDA (kelimenin başında veya sonunda) TAM ÖRNEK BULMA: \b

Örnek: Kelimenin başında :/\bert/ ert örneğiyle başlayan kelimeleri bulur. Örneğin ert,ertan gibi kelimeleri bulur bertan bulunmaz. Kelimenin sonunda :/ert\b/ kelimenin sonunda ert örneği olanları bulur. Örneğin ert,mert kelimeleri bulunur ertan,bertan bulunmaz. Şu örnekte ise sadece ert kelimesi bulunur. /\bdef\b/

Pekala şöyle bir soru aklımıza gelebilir. kelimemiz $ertan olsaydı ,/\bert/ patterni ile bu ert kelimesi bulunurmuydu? -Evet. Çünki Enbaştaki $ karakteri stringin değişken olduğunu belirten karakter olup dikkate alınmazdı.

KELİME İÇİNDE TAM ÖRNEK BULMA: \B

Bunu anlamak için yine örneklere bakalım. /\Btan/ patterni, bulacağı örnek mesela ertan dır. tan kelimesinde test olumsuzdur. Benzer şekilde /tan\B/ patterninde taner kelimesi aranan örneğe uyar ve /\Btan\B/ pattern ine uyan örnekler mesela utanan,dartanyan olup. tan,ertan,taner uymaz. Bu karakterler (\b,\B) bize, bir kayıt(satır)dan ,split komutunu kullanmaksızın kelime arama imkanını, sağlar.

Örnek Program : Bu kelimesini içeren satırların sayısını veren program.pat6.pl

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

 $sayi = 0;

  print ("Satırları Giriniz !:\n");

  $satir = <STDIN>;

  while ($satir ne "") {

          if ($satir =~ /\bBu\b/) {

             $sayi += 1;

        }

         $satir = <STDIN>;

 }

  print ("'Bu' kelimesi içeren satir adeti: $sayi\n");

Çalışması :

>pat6.pl

    Satırları Giriniz !:

    Bu birinci satır.

    Bu ikinci satır.

    Bu üçüncü satır.

    Sondan önceki satır

    Son satır.

    ^D

    'Bu' kelimesi içeren satir adeti: 3
>

Bu örnekte bir satırda kaç adet Bu kelimesi olduğunu düşünmedik. Sadece Bu kelimesi var mı şeklinde test ettik.Bir satırda birden fazla Bu kelimesi geçiyor ve biz kaç adet Bu geçtiğini bulmak istersek şu şekilde kodlama yapabiliriz.

if ($satir =~ /\bBu\b/) { 

            @kelimeler_dizisi = split(/[\t ]+/, $satir);

            $say = 1;

            while ($say <= @kelimeler_dizisi) {

                    if ($kelimeler_dizisi[$say-1] eq "Bu") {

                            $adet += 1; # kac adet Bu olduğu burada tutulur.

                    }

                    $say++;

            }

    }

veya daha kısa olarak şöyle de kodlayabiliriz.

if ($satir =~ /\bBu\b/) {

            @kelimeler_dizisi = split(/\bBu\b/, $satir);

            $adet += @kelimeler_dizisi - 1;

}

Hatta if kullanımına hiç gerek yoktur.

	@kelimeler_dizisi = split(/\bBu\b/, $satir);
 
	$adet += @kelimeler_dizisi - 1;

kodlaması yeterlidir. Çünkü satır otomatikman aranacaktır ve varsa Bu kelimesi yeni bir kelimeyi (dolayısıyla yeni bir dizi elemanını)başlatan ayraç olacaktır. Dolayısıyla diziler 0.elemandan başladığından dizi boyutunun 1 eksiği bulunan kelime adedini verecektir.

Pattern leri bir değişken içinde saklayarak,testlerde bu değişkenleri de kullanabiliriz.

$pattern = "[\\t ]+";

	@kelimeler_dizisi = split(/$pattern/, $satir); .. gibi.

Örnek Program : Program Adı pat7.pl.İki dosyamız olsun. Kullanacağımız dosyaların adları bilgi.dat ve alan.dat olup içeriği ise,

Bu ilk kayıttır.

İkinci kayit.

Dosyadaki son kayit.

şeklinde olsun. Bu dosyaların adlarını komutsatırından girip,bir string 'i(pattern) bu dosyalarda taratalım.Taranacak string "kayit" olsun. Program stringi bulduğu takdirde hangi dosyada ve hangi kayıtta (satırda) olduğunu ekrana bassın.

Göster Gizle Kopar Satır Gizle Satır Göster
#!/usr/local/bin/perl

 print ("Aranacak kelimeyi giriniz : ");

 $aranankelime = <STDIN>;

 chop ($aranankelime);

 $dosya_adi = $ARGV[0];

 $satirno = $bulunansayisi = 0;

 while ($satir = <>) 

 {

        $satirno += 1;

        if ($satir =~ /$aranankelime/) 

         {

          print ("$dosya_adi, satir $satirno\n");

          @kelimeler = split(/$aranankelime/, $satir);

          $bulunansayisi += @kelimeler - 1;

         }

        if (eof) 

         {

          $satirno = 0;

          $dosya_adi = $ARGV[0];

         }

 }

 if ($bulunansayisi == 0) 

  {

    print ("String bulunamadı !!! \n");

  } else 

    {

     print ("Bulunan $aranankelime kelimesi sayısı: $bulunansayisi\n");

    }

Çalışması:

>pat7.pl alan.dat bilgi.dat

 Aranacak kelimeyi giriniz : kayit

 alan.dat, satir 2

 alan.dat, satir 3

 bilgi.dat, satir 2

 bilgi.dat, satir 3

 Bulunan kayit kelimesi sayısı: 4

>

Dosya Listesi

İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır