Regular expressions – Düzenli ifadeler

 

Öncelikle Yüksek Lisans öğrencim “Mustafa Salih Bahar”a teşekkürler. Bu bölümde Python ortamında düzenli ifade kullanımı göreceğiz.

Düzenli ifadeler tüm modern programlama dillerde bir standart haline gelmiştir. Karmaşık bir metin içerisinde istediğimiz formattaki metinleri yakalayabilmemize imkân tanır. Mesela, bir kaynakta geçen tüm e-posta adreslerini veya içinde rakam bulunan ve gmail uzantılı olan mail adreslerini ayıklamak için kullanabilirsiniz. Düzenli ifadeler olmasaydı ardı arkasına birçok if — else yazmak gerekebilirdi. Bu modül, birkaç saatte yapabileceğiniz bir işlemi saniyeler içerisinde sizin yerinize yapabiliyor.

1. Kurulum

Python ile standart olarak gelen bir kütüphanedir. Kurulum gerektirmez.

şeklinde projeniz içerisine aktardıktan sonra kullanmaya başlayabilirsiniz.

2. Fonksiyonlar

2.1. search()

Bu fonksiyon, aranılan bir içeriğin ilgili metin içerisinde olup olmadığını kontrol eder.

Metin içerisinde geçen Mustafa kelimesini arattırdık, dikkat edersek span ve match diye alanlar var. Burada match aradığımız değeri, span ise nerede olduğunu gösterir. Aradığımız yerdeki 12. ve 19. harfler arasındaymış o zaman kontrol edelim.

Gördüğümüz gibi tekrar Mustafa değeri döndü. search() fonksiyonu ilgili metnin nerede olduğunu başarıyla bize söyleyebildi.

2.2. start()

Bu fonksiyon aratılan kelimenin, kaynakta nerede geçtiğini döndürür. Yukarıdaki örnekte (12,19) arasında olduğunu biliyoruz. Sadece buradan 12 değerini çekmek istersek kullanabiliriz.

2.3. end()

Üstteki start() fonksiyonunun tersini yapar, yani aratılan kelime hangi aralıkta geçiyorsa onun son değerini döndürür. Kaynakta Mustafa kelimesinin (12,19) arasında geçtiğini biliyoruz. Start fonksiyonu 12 dönmüştü, end() fonksiyonu da 19 değerini dönecektir.

2.4. endpos()

Kaynak içerisindeki karakterlerin toplam sayısını döndürür. \n gibi satır atlatma karakterleri de sayılır.

İlk metin değişkeni içine bir içerik yazdık, sonra içinde Mustafa geçiyor mu diye bakarak sonucu bir kontrol objesine atadık, ardından endpos() ile 38 karakter olduğunu gördük, sonra metin değişkenini 38’ya kadar görüntüledik ve doğruluğunu teyit ettik.

2.5. findall()

Bu fonksiyon ile bir kaynak içerisinde istediğimiz metnin kaç kere geçtiğini inceleyebiliriz.

Oluşturduğum metin içerisinde zaman kelimesi var mı diye sorguladık. Liste olarak geri döndü. Eğer bunu adet olarak görmek isteseydik len() fonksiyonundan geçirebilirdik.

Bu şekilde 2 kere geçtiğini de görmüş olduk.

3. Metakarakterler

Bu noktaya kadar bir kaynak içerisinde belirli bir metin aradık, ancak bu modülü güçlü yapan şey bu noktadan sonra anlatacağımız metakarakterlerdir. Bu metakarakterler sayesinde, belirlediğimiz bir düzene uyan metinleri arayabiliriz. Mesela salih metnini aramak yerine, salih, selih, fetih, fatih gibi belirli bir şablon içerisine giren metinleri de arayabiliriz. İşte bunu yapmamızı sağlayan, aranılan metne eklediğimiz bazı özel karakterler var, bu karakterleri inceleyelim.

3.1. . Karakteri

Yeni satır karakteri hariç herhangi tek bir karakterin yerini tutar.

Mesela bu örnek içerisinde zaman ve saman kelimelerini buldu. Çünkü herhangi bir karakter ile başlayıp aman ile devam eden bir şablon belirledik.

3.2. * Karakteri

Bir ifadenin bütün tekrarlanmalarını bulur.

g harfinden sonra * koyduk, yani bu g karakteri 0 kere de geçebilir 100 kere de geçebilir. Bu ayrım sadece kendinden önceki harfi kapsıyor. Bu nedenle @mail, @gmail ve @ggggggmail döndü.

3.3. + Karakteri

Kendinden önce gelen karakterin bir veya daha fazla kullanılmasını arar. Üstte yaptığımız * ile ilgili örneği bu sefer + ile yaparsak;

şeklinde @gmail ve @ggggggmail döner. Çünkü g harfinden sonra + koyarak bu harfin 1 veya daha fazla geçmesi gerektiğini söyledik.

3.4. ? Karakteri

Kendinden önce gelen karakterin 0 veya 1 kere tekrar etmesini sorgular.

Dikkat edilirse @ggggggmail dönmedi çünkü 0 veya 1 kere olmasını sorguladık, 1’den fazla olanlar bu sonuca dahil değildir.

3.5. [] Karakteri

Bu köşeli parantezler arasına yazılan bütün karakterler sorgulanır.

Bu şablonda H veya B ile başlayan sonrasında ilal ile devam eden bir şablon belirledik ve Hilal, Bilal sonuçlarını aldık.

Burada ise s ile başlayan a veya i artı m ile devam eden, e veya i artı t ile biten sonuçları aradık. Sonrasında samet ve simit sonuçlarını başarıyla gördük.

Biraz daha işleri karıştıralım. Köşeli parantez kullanırken aralık da belirleme imkânımız vardır.

  • [A-Z] A’dan Z’ye tüm büyük harfler.
  • [a-z] A’dan Z’ye tüm küçük harfler.
  • [0–9] 0’dan 9’a tüm rakamlar.
  • [1–4] 1’den 4’e tüm rakamlar.

O zaman madem Hilal ve Bilal büyük harf ile başlıyor, şöyle yazalım.

A-Z arasındaki büyük bir harfle başlayan ve sonra ilal ile devam edenleri bulduk. Peki küçük harfle arasaydık ne olurdu?

Gördüğümüz gibi hiçbir sonuç dönmedi. Çünkü Hilal ve Bilal büyük harfler ile başlıyor.

3.6. {} Karakteri

Belirli bir sayıda tekrar anlamındadır. Şimdi yukarıda öğrendiklerimiz ile birlikte biraz daha karışık bir örnek yapalım. Kaynağımız Bence saat tamir etmek zor zanaat. olsun. Burada küçük harflerle başlayan aat ile biten her şeyi yakalamak istedik.

  • Adım 1: [a-z] ile küçük harf ayrımı yapmamız gerek.
  • Adım 2: [a-z]* ile küçük harflerden 1 veya n (sonsuz) kere geçmesini söyledik.
  • Adım 3: [a-z]*a ile küçük harf ile başlayıp a ile devam etsin dedik.
  • Adım 4: [a-z]a{2} ile a harfinden 2 adet olması gerektiğini belirttik.
  • Adım 5: [a-z]a{2}t en son da t ile bitsin dedik.

3.7. ^ Karakteri

İfadenin başlangıcını kontrol eder ve [ ] karakterleri ile birlikte kullanılırsa da hariç anlamına gelir.

Kaynağımız Oku ile başladığı için ilk örnek başarıyla ^Oku sayesinde çalıştı. Ancak diğer örnekte ^sesli ayracı bir şey dönmedi, halbuki kaynak içerisinde bu metin var fakat başında değil.
Bu meta karakter sabit bir metin için kullanışlı gelmeyebilir. Çünkü zaten metnin başını gözle de görebiliyorsunuz, fakat bir listeyi for döngüsüne sokarak böyle bir metakarakter kullanılırsa çok faydalı olabilir. Bir örnek yapalım.

Örnek içerisinde metin değişkenindeki içeriği split() fonksiyonu ile kelime kelime parçalayıp liste içerisine attık. Sonra da bir for döngüsü ile her bir kelimeyi kontrol ederek büyük harfli kelimeleri ayırdık.
Şimdi de plakayı biraz uzun bir yol kullanarak bulalım.

[ ] arasındaki A-Za-z ifadesi büyük veya küçük harf anlamını taşıyor. Başına da ^ eklediğimizde büyük veya küçük harf ile başlamasın demiş oluyoruz. Sonra 0–9 ile devam etsin sonra tekrar büyük harf ve sonra tekrar 0–9 ile devam etsin. Sonuç olarak plakayı çektik.

3.8. $ Karakteri

Yukarıda, ^ karakteri ile bir ifadenin başlangıcını kontrol etmiştik, $ metakarakteri ile de ifadenin sonunu yani ne ile bittiğini kontrol edebiliyoruz.

Örnek bir metin oluşturup içerisinde google.com ve apple.com alan adlarını yerleştirdik. Ardından bu metni split() fonksiyonu ile bir liste içerisine aldık. Sonra bir for döngüsü ile her bir kelimenin .com ile bitip bitmediğini, eğer bitiyorsa ekrana yazmasını istedik. Bu şekilde bir metinde geçen .com ile biten kelimeleri çıkarabildik.
Eğer buradaki .com veya .net ile bitenleri bulmak istersek aradaki veya ifadesini karşılamak için | karakterini kullanıyoruz. Örnek;

Bu kod parçası da metin içerisinde geçen .com veya .net geçenleri ekrana bastırır.

3.9. | Karakteri

Yukarıdaki örnek içerisinde kullanılmıştı, veya anlamına gelir.

Kaynaktan siyah veya beyaz metinlerini aldık. Arama yaparken birden fazla değeri kaynak içerisinde bulmayı mümkün kılar.

3.10. ( ) Karakteri

Parantez de yazdığımız kalıpları gruplamak için kullanılır. Matematikteki bölme ve çarpma için öncelik belirlerken kullandığımız parantez gibi düşünebiliriz.

3.11. \ Karakteri

Kaçış dizisidir. Buraya kadar birçok karakter gördük, mesela bunlardan biri de $ simgesi. Bir ifadenin sonunu kontrol etmek için kullanıyorduk. Ancak bu bir dolar simgesi ve bazen bir para birimi olarak da kaynak içerisinde bulunabilir, ve biz bunları ayıklamak isteriz. Mesela;

0–9 ile başlayan sonra $ ile devam eden bir arama yaptığımızda eğer ters slash koymazsak python bunun özel bir anlam ifade ettiğini zannediyor ve sonuç döndürmüyor. Kaçış karakteri kullandığımızda ise başarıyla fiyatları döndürüyor.

4. Meta Sequences

Metakarakter gibi ama özel bir anlam ifade eden yapılar var son olarak onlara bakalım.

4.1. \s ve \S İfadesi

Bu ifade kaynaktaki boşluğu yakalar. Büyük harfle yazılan hali ise boşluk haricindekileri yakalar.

Metin içinde kaç tane boşluk olduğunu görmek için \s ifadesini kullandım. Sonra len() fonksiyonu ile adedini ekrana bastırdık.

Boşluk haricindekileri bulmak istersek, onu da \S ile yapıyoruz.

4.2. \d ve \D İfadesi

Bu ifade kaynaktaki sayıyı yakalar. Büyük harfle yazılan hali ise sayı olmayanları yakalar.

Başarıyla kaynaktaki sayıları yakaladık. Sayı haricindekileri yakalayalım.

4.3 \w ve \W İfadesi

Bu ifade kaynaktaki karakter, sayı ve alt çizgiyi yakalar. Büyük harfle yazılan hali ise tam tersini yani boşluk, nokta, soru işareti, boşluk gibi karakterleri yakalar.

\w kullanıldığında % @ ve ? simgeleri gelmezken \W kullanıldığında geliyor.

Kaynaklar

  • https://www.sinanerdinc.com/python-re-modulu
  • https://docs.python.org/3/contents.html
  • https://www.tutorialspoint.com/python/index.htm
  • https://www.w3schools.com/python/