Python ile metin işlemek

Pyparsing kütüphanesine merhaba diyelim

Bu bölümde pyparsing kütüphanesinin çok temel bir kullanımını öğrenip bir Sosyal Güvenlik Numarası nasıl işlenir onu öğreneceğiz.

Metin işleme araçları

Python ile metin işleme için kullanabileceğiniz olanaklardan bir tanesi düzenli ifadeler. Ancak düzenli ifadeler oldukça karmaşık olabiliyor. Bunun yerine Python için pyparsing kütüphanesinden faydalanabilirsiniz.

Pyparsing hakkında

Pyparsing kütüphanesi (https://pyparsing.wikispaces.com/) metin işleme için kullanılan bir kütüphanedir. Paul McGuire tarafından geliştirildi. pip kullanarak kolaylıkla kurabilirsiniz.

İlkönce neyin eşleşmesi gerektiğini belirten bir gramer, yazım kuralı oluşturuyoruz. Daha sonra bu yazım kuralının metin işleme işlevini çağırıyoruz. Bu işlev metini işlerken boşlukları otomatik olarak atlayabilir.

Pyparsing metin işleme konusunda nelerin eşleşeceğini, tekrarlanan öğeleri ve bundan da fazlasını içeren bir çok işlev sunar.

Not : Bu örnekler Python3 ile yazılmıştır. Ancak print() yazdırma işlevini print haline çevirirseniz Python2 ile de çalışacaktır.

Bir yazım kuralı oluşturalım

Pyparsing'i kullanmanın ilk adımı bir yazım kuralı oluşturmaktır. Bir yazım kuralı hedef metnin tam olarak ne içereceğini tanımlar. Bunu yapmanın en iyi yolu yukarıdan aşağıya doğru hareket etmektir. İlk önce tüm metni belirtiyor, daha sonra bunları parçalara bölmek suretiyle harf düzeyine inene kadar devam ediyoruz.

Yazım kuralı için kullanılan gösterim Backus-Naur Biçemi ya da kısaca BNF olarak adlandırılır. Kuralları tam olarak BNF ile yazmak konusunda endişelenmenize gerek yoktur ama ileride parçaların nasıl bir araya geldiğini anlamak açısından önemlidir.

Temel yazım şekli

remiz ::= ifade

şeklindedir.

Bu remizin ifadede belirtilen kısımlardan oluştuğunu belirtir. Örneğin bir kişi ismi şu şekilde tanımlanabilir :

isim ::= ilkİsim [ikinciİsim] soyİsim
ilkİsim ::= harf | ilkİsim harf # bir ya da daha fazla harf
soyİsim ::= harfler+ #bir ya da daha fazla harfin kısa yoldan gösterim biçimi
harf = 'a' | 'b' | 'c' vs.

Bu bir ismin ilk isim, isteğe bağlı ikinci isim (isteğe bağlı bileşenler köşeli parantezlerle gösteriliyor) ve soy isimden oluştuğunu gösteriyor. İlk isim, soy isimde olduğu gibi bir ya da fazla harften oluşabilir. Artı işareti bir ya da daha fazla anlamına gelir.

Pyparsing harfler, rakamlar ve karakter kümeleri için önceden tanımlı remizlere sahiptir.

Basit bir metin işleyici

Pyparsing kütüphanesini kullanabilmek için programımıza eklememiz gerekiyor. Bunu da import komutu ile yapıyoruz.

from pyparsing import *

Sosyal güvenlik numarasına bakalım. Yazım şekli RRR-RR-RRRR şeklindedir. Burada R herhangi bir rakam olabilir. BNF kullanarak sosyal güvenlik numarasının yazım kuralını yazarsak

sgn ::= numara + '-' numara + '-' numara+
numara ::= '0' | '1' | '2'

Yukarıdaki gibi olacaktır.

Pyparsing ile belirli sayıda rakamı şu şekilde ifade edebiliriz.

Word(nums, exact = kaçtane)

Burada kaçtane kısmına örneğin 2 rakam olmasını istiyorsak 2 yazabiliriz. Bu yazım biçimini kullanırsak :

kesme = '-'
sosyalGüvenlikNumarası = Word(nums, exact = 3) + kesme 
+ Word(nums, exact=2)
+ kesme + Word(nums, exact=4)

Metin işleme için parseString() işlevini kullanıyoruz.

numara = '123-45-6789'
sonuç = sosyalGüvenlikNumarası.parseString(numara)
print (sonuç)

Ekrana yazdırdığımız sonuç şu şekilde oluyor.

['123', '-', '45', '-', '6789']

Eğer istersek Combine() işlevini kullanarak sonucu tek bir ifade olarak da gösterebiliriz.

sosyalGüvenlikNumarası = Combine(Word(nums, exact = 3)
                        + kesme
                        + Word(nums, exact=2)
                        + kesme
                        + Word(nums, exact=4))

Bu değişiklikle beraber sonuç şu şekilde oluyor :

['123-45-6789']

Programın tamamını kolaylık olması açısından yazarsak şu şekilde olacak :

from pyparsing import *

# sgn ::= numara + '-' numara + '-' numara+
# numara ::= '0' | '1' | '2'

kesme = '-'
sosyalGüvenlikNumarası = Word(nums, exact = 3)
                        + kesme
                        + Word(nums, exact=2)
                        + kesme
                        + Word(nums, exact=4)

numara = '123-45-6789'
sonuç = sosyalGüvenlikNumarası.parseString(numara)
print (sonuç)

Programı biraz daha geliştirelim

Programı biraz daha geliştirelim ve karmaşık bir metin dosyasından sosyal güvenlik numaralarını okutmayı deneyelim. Öyle ya her zaman okuma yaptığımız kaynakta veriler sıralı olmayabilir.

from pyparsing import *

# yazım şekli, gramer

# sgn ::= numara+ '-' numara+ '-' numara+
# numara ::= '0' | '1' | '2' vs. vs.

kesme = '-'


sosyalGüvenlikNumarası = Combine(Word(nums, exact=3)
                                + kesme
                                + Word(nums, exact=2)
                                + kesme
                                + Word(nums, exact=4))

girişMetni = """
  aaa 225-92-8416 bbb
  103-33-3929 ccc 028-91-0122
"""

for eşleşen, başlangıç,
    bitiş in sosyalGüvenlikNumarası.scanString(girişMetni):
    print (eşleşen, başlangıç, bitiş)

Programın çıktısına bakalım :

['225-92-8416'] 7 18
['103-33-3929'] 25 36
['028-91-0122'] 41 52

Görebileceğiniz üzere bu sefer SGN numaralarının hangi karakterden itibaren başlayıp bittiğini de göstermiş olduk.

İleriki derslerde görüşmek üzere. Şimdilik hoşça kalın !

Yorumlar

yorum yaz

Yorum yaz

Henüz yorum yok.