Düzenli ifadeler elle yapılması saatler alacak olan bir işlemi saliseler içinde yapmamızı sağlar.Düzenli ifadeler ile karakter dizileri üzerinde işlemler yapabiliriz.Burada hemen şunu da söyleyelim ki; eğer yapmak istediğimiz işlemi karakter dizileri metotları ile yapabiliyorsak kesinlikle bu metotları kullanmalıyız. Çünkü karakter dizileri metotları hem daha basit hemde çok daha hızlıdır.
Düzenli ifadeler Python programlama dilinin en zor konularından biridir. Ama öğrendikten sonra çok zor olan işlemleri çok basit bir şekilde yapmamızı sağlar. Zorluğundan dolayı kavrayabilmek için bol bol örnek çözülmesi gereken bir konudur.
Kullanım Yerleri
Nasıl yazıldığını tam olarak bilmediğimiz bir karakter dizisini aratabiliriz.
Pythonda düzenli ifadeler ile ilgili her şey bir modül içinde tutulmaktadır. Bu modülün adı "re(regular expression)"dır. Tabi ki bu modülü kullanabilmemiz için ilk önce içe aktarmamız gerekir.
Match() Metodu
match() metodu bir karakter dizisinin bizim aradığımız bir başka karakter dizisi ile başlayıp başlamadığını kontrol eder. Yani karakter dizisinin sadece en başına bakar.
En başta da söylediğimiz gibi match() metodu karakter dizisinin sadece en başına bakar.Gelin şu şekilde bir örnek verelim:
Biz bu yaptığımız işlemleri karakter dizisi metotları ile yapabilir miyiz?
match() metodu bize bir eşleştirme nesnesi döndürüyor ve biz bulunan şeyi göremiyoruz. Eğer görmek istersek group() metodunu kullanabiliriz.
Eğer eşleştirme nesnesi değilde geriye "None" ifadesi dönerse group() metodu hata verecektir.
match() metodu karakter dizisinin sadece en başına bakıyor ve bir eşleştirme işlemi yapıyordu. search() metodu ise karakter dizisinin genelinde bir arama işlemi yapar.
Not:match() metodunda bahsettiğimiz eşleşme nesneleri metodları search() metodu içinde geçerlidir.
Not:Düzenli ifadeler sadece karakter dizileri üzerinde işlem yapmamızı sağlar.Listeler, sözlükler gibi yapılar üzerinde doğrudan düzenli ifadeleri kullanamayız.
findall() metodu karakter dizisi içinde aranan öğrenin hepsini bir liste şeklinde geriye döndürür.
Şimdiye kadar kullandığımız düzenli ifadelerde, düzenli ifade ve karakter dizisi arasında doğrudan bir eşleşme yaptık. Bu yaptıklarımız düzenli ifadelerin en temel halidir. Yani "python" düzenli ifadesini karakter dizisinde bulmak için "python" kelimesini kullandık. "python" düzenli ifadesini doğrudan kendisi ile eşleştirmiş olduk. Peki bunları neden söylüyoruz ? Düzenli ifadelerden bu şekilde doğrudan eşleştirme yapmadan da arama yapmamızı sağlayan ifadeler vardır. Zaten düzenli ifadeleri özel kılan bu ifadelerdir.
Bu ifadelere Python'da metakarakterler denir. Aslında biz metakarakterleri daha önceden de kullanmıştık.
Python da bulunan metakarakterler:<\br> [ ] . * + ? { } ^ $ | ( )<\br> Şimdi gelin bu karakterleri sırası ile işlemeye başlayalım. Zaten açıkladıkça ne demek istediğimiz anlayacaksınız.
[ ](Köşeli Parantez)
[] metakarakterini açıklamaya çalışmak yerine gelin hemen örnek verelim.
Bu örnekte search() metodunu kullandığımıza dikkat edin. Şimdi gelin match() metodunu kullanarak yeni örnek yapalım.
.(Nokta)
"." metakarakteri yeni satır hariç bütün karakterleri temsil etmek için kullanılır. [] metakarakterinde verdiğimiz örneği değiştirelim.
"*" metakarakteri düzenli ifadede konulduğu yerden bir önceki karakteri sıfır veya daha fazla sayıda eşitler. Tanımı biraz karışık ama örnek verince netleşecektir.
Burada yazdığımız düzenli ifade ile aradığımız ifadenin "k" ile başlamasını sonra sıfır veya daha fazla sayıda "o" ile davam etmesini ve "d" ile bitmesi gerektiğini söylüyoruz.
Şimdi gelin daha önceden öğrendiğimiz "." metakarakteri ile "*" metakarakterini birleştirelim ve bakalım ne olacak?
"*" sayesinde match() metodunu search() metodu gibi de kullanabiliriz. Daha önceden search() ile yaptığımız örneği şu hale getirelim.
+(Artı)
"+" metakarakteri "*" metakarakterine oldukça benzerdir. "*" kendisinden önceki sıfır veya daha fazla sayıda tekrar eden karakterleri ayıklıyordu."+" ise kendisinden önceki bir veya daha fazla sayıda tekrar eden karakteri ayıklar.
"*" metakarakterini işlerken verdiğimiz örneği hatırlarsanız, "kd" ögesini de çıktı olarak alıyorduk. Biz her zaman böyle olmasını istemeyebiliriz. Aradığımız karakterin öge içinde en az bir kere geçmesini istediğimiz durumlarda "*" yerine "+" metakarakterini kullanmalıyız.
Hatırlarsanız [] metakarakterini işlerken şöyle bir örnek vermiştik.
?(Soru İşareti)
Önceki bölümlerde işlediğimiz "*" metakarakteri eşleşmenin sıfır veya daha fazla olduğu durumlarda "+" metakarakteri ise eşleşmenin bir veya daha fazla olduğu durumlarda kullanılıyordu. "?" metakarakteri ise eşleşme sayısının sıfır veya bir olduğu durumlarda kullanılır.
Daha önce yaptığımız örneğin üç metakarakter ile kullanımını gösterelim ki aradaki farkı net bir biçimde görelim.
{}(Küme Parantezi)
{} merakarakteri sayesinde bir eşleşmenin kaç adet olması gerektiğini belirtebiliyoruz.
{} küme parantezinin bir başka kullanım şekli ise; bir karakterin en az ve en çok kaç kere tekrar etmesi gerektiğini söyleyebiliyoruz. Hemen örneğine bakalım.
Hatırlarsanız daha önceki konularda match() ve search() metodlarını işlemiştik. match() metodu arama yaparken ifadenin sadece başına bakar search() metodu ise aranılan ifadeyi tüm öge içinde arardı.
^ metakarakteri ile ise search() motodu ile arama yaparken match() metodu gibi ifadenin sadece başına bakmasını istediğimizi belirtiyoruz.
"^" metakarakterinin bir görevi daha vardır. Hariç anlamında da kullanılır. Yani arama işlemi yaparken belli bir koşula uyan ifadeleri almak istemeyebiliriz. Bu durumlarda da "^" metakarakterini kullanabiliriz.
$(Dolar)
"$" metakarakteri bir önceki bölümde incelediğimiz "^" metakarakterinin tam tersi işi yapar. "^" karakteri ile karakter dizilerinin nasıl başlayacağını belirtiyorduk. "$" metakarakteri ile de nasıl biteceğini belirtiyoruz.
Elimizde şu şekilde bir isim listesi olsun ve biz bu listeden ismi "an" ile bitenleri ayıklayalım.
Not: Burada önemli olan "^" ve "$" metakarakterlerini search() metodu ile kullanmanız gerektiğidir. Eğer match() metodu ile kullanırsanız herhangi bir çıktı alamazsınız.
Ters Bölü
"\" işareti daha önceden de bildiğimiz kaçış dizisidir. Şimdiye kadar işlediğimiz metakarakterler kendileri ile eşleşmiyorlar. Yani bu metakarakterleri bir karakter dizisinde aramak istesek özel anlamları yüzünden bu mümkün olmayacaktır. İşte bu özel anlamlarını iptal edip bu karakterleri Python'a normak karakter gibi göstermek için "\" kaçış dizisini kullanıyoruz.
|(Dik Çizgi)
"|" metakarakteri "veya" anlamına gelir. Birden fazla eşleştirme kalıbı kullanılmak istenen durumlarda kullanılır.
Bir önceki başlıkta verdiğimiz örnek üzerinden gidelim.
Elimizdeki bir listede herhangi bir ögenin kendisini yazıyorsak da bu metakarakteri kullanabiliriz.
"()" metakarakteri düzenli ifade kalıplarını gruplamamızı sağlar. Bu metakarakter sayesinde bir karakter dizisinin istediğimiz bölümlerini çok rahat bir şekilde ayıklayabiliriz.
İleride eşleşme nesneleri metotlarından group() metodunu işlerken örnekler vereceğiz.
Düzenli ifadeler Python programlama dilinin en zor konularından biridir. Ama öğrendikten sonra çok zor olan işlemleri çok basit bir şekilde yapmamızı sağlar. Zorluğundan dolayı kavrayabilmek için bol bol örnek çözülmesi gereken bir konudur.
Kullanım Yerleri
Nasıl yazıldığını tam olarak bilmediğimiz bir karakter dizisini aratabiliriz.
- Örneğin; "congratulations" karakter dizisinin bulmak istiyor ve yazılışını tam olarak bilmiyorsak ilk ve son bir kaç karakterini verip aratabiliriz.
- Örneğin; bir metin içindeki tüm URL'leri ana yapıyı tarif ederek ayıklayabiliriz.(http:// ile başlayan ve arada noktalar içeren kelimeler.)
- Örneğin; kullanıcıdan e-posta istediğimizde formatını kontrol edebiliriz. (@ içerecek ve ikinci blokta bir nokta bulunacak.)
- Örneğin; Bir metin dosyasından aldığımız verileri kullanmak için Php dizisine dönüştürebiliriz.
Pythonda düzenli ifadeler ile ilgili her şey bir modül içinde tutulmaktadır. Bu modülün adı "re(regular expression)"dır. Tabi ki bu modülü kullanabilmemiz için ilk önce içe aktarmamız gerekir.
import reBu kod parçacığı ile modülü içe aktarmış olduk. Şimdi gelin bu modülün bize sunduğu tüm özellikleri listeleyelim.
#!/usr/bin/env python # -*- coding: utf-8 -*- import re for i in dir(re): print i DEBUG DOTALL I IGNORECASE L LOCALE M MULTILINE S Scanner T TEMPLATE U UNICODE VERBOSE X _MAXCACHE __all__ __builtins__ __doc__ __file__ __name__ __package__ __version__ _alphanum _cache _cache_repl _compile _compile_repl _expand _pattern_type _pickle _subx compile copy_reg error escape findall finditer match purge search split sre_compile sre_parse sub subn sys templateGördüğünüz gibi düzenli ifadeler bize bir çok metot/fonksiyon kullanma imkanı veriyor. Eğer herhangi bir metot/fonksiyon hakkında bilgi almak isterseniz. help(metot/fonksiyon adi) şeklinde kullanabilirsiniz.
#!/usr/bin/env python # -*- coding: utf-8 -*- import re print help(re.escape) Help on function escape in module re: escape(pattern) Escape all non-alphanumeric characters in pattern.Gelin şimdi biz bu metotlar içinde en sık kullanılanları açıklayalım.
Match() Metodu
match() metodu bir karakter dizisinin bizim aradığımız bir başka karakter dizisi ile başlayıp başlamadığını kontrol eder. Yani karakter dizisinin sadece en başına bakar.
#!/usr/bin/env python # -*- coding: utf-8 -*- import re karakter = "python programlama dilini öğreniyorum." print re.match("python",karakter)Düzenli ifade kalıpları match() metodunun ilk argümanıdır. İkinci argüman ise arama yapacağımız karakter dizisidir.Yukarıdaki kodları çalıştırdığınızda şu şekilde bir çıktı alacaksınız.
<_sre data-blogger-escaped-.sre_match="" data-blogger-escaped-0xb728e790="" data-blogger-escaped-at="" data-blogger-escaped-object="">Bu ifade karakter dizisinin düzenli ifade ile eşleştiği anlamına gelir. match() metodu düzenli ifade ile karakter dizisinin eşleşip eşleşmediğini bize söyler. Eşleşti deyiş biçimi de bu şekildedir. Bu ifadeye Python'da "eşleşme nesnesi" denir.
print re.match("delphi",karakter) NoneBurada eşleşme olmadığı için match() metodu geriye "None" ifadesi döndürdü. Yani match() metodu geriye eşleşme varsa "eşleşme nesnesi" yoksa "None" ifadesi döndürür.
En başta da söylediğimiz gibi match() metodu karakter dizisinin sadece en başına bakar.Gelin şu şekilde bir örnek verelim:
import re karakter = "python programlama dilini öğreniyorum." print re.match("programlama",karakter) None"programlama" kelimesi karakter dizisi içinde bulunduğu halde "programlama" ile başlamadığı için match() metodu geriye "None" ifadesini döndürdü.
Biz bu yaptığımız işlemleri karakter dizisi metotları ile yapabilir miyiz?
karakter = "python programlama dilini öğreniyorum." print karakter.split()[0]=="python" True
print karakter.split()[0]=="programlama" False
print karakter.startswith("python") TrueBizim düzenli ifadelerden beklediğimiz sadece karakter dizisinin başlangıç ifadesini kontrol etmekse bunu karakter dizisi metotları ile yapmamız daha mantıklı olacaktır. Çünkü split() ve startswith() metotları match() metoduna göre hem daha basit hemde hızlıdır.
match() metodu bize bir eşleştirme nesnesi döndürüyor ve biz bulunan şeyi göremiyoruz. Eğer görmek istersek group() metodunu kullanabiliriz.
import re karakter = "python programlama dilini öğreniyorum." kontrol = re.match("python",karakter) print kontrol.group() pythonBurada re.match("python",karakter) metodu ile dönen eşleştirme nesnesini bir değişkene atadık. Bu eşleştirme nesnesinin de kendi metotları bulunmaktadır.
import re karakter = "python programlama dilini öğreniyorum." kontrol = re.match("python",karakter) for i in dir(kontrol): print i __class__ __copy__ __deepcopy__ __delattr__ __doc__ __format__ __getattribute__ __hash__ __init__ __new__ __reduce__ __reduce_ex__ __repr__ __setattr__ __sizeof__ __str__ __subclasshook__ end endpos expand group groupdict groups lastgroup lastindex pos re regs span start stringListedeki metotlar eşleştirme nesnesi metotlarıdır. Dikkat ederseniz az önce kullandığımız group() metodu da listede bulunmaktadır.
Eğer eşleştirme nesnesi değilde geriye "None" ifadesi dönerse group() metodu hata verecektir.
import re karakter = "python programlama dilini öğreniyorum." kontrol = re.match("programlama",karakter) print kontrol.group() Traceback (most recent call last): File "/home/mazlumagar/workspace/Python/Duzenli İfadeler/match.py", line 9, in print kontrol.group() AttributeError: 'NoneType' object has no attribute 'group'Bu hata mesajı programın çökmesine sebep olur. Bu yüzden kodlarımızı şu şekilde yazabiliriz.
import re karakter = "python programlama dilini öğreniyorum." kontrol = re.match("python",karakter) if kontrol: print "Eşleşen kelime: " + kontrol.group() else: print "Eşleşme başarısız."search() Metodu
match() metodu karakter dizisinin sadece en başına bakıyor ve bir eşleştirme işlemi yapıyordu. search() metodu ise karakter dizisinin genelinde bir arama işlemi yapar.
import re karakter = "python programlama dilini öğreniyorum." print re.match("programlama",karakter) NoneBu örneği hatırlarsanız; match() metodu burada karakter dizisinin başında "programlama" ifadesini bulamadığı için "None" ifadesi döndürüyordu. Şimdi aynı örneği search() metodu ile yapalım.
import re karakter = "python programlama dilini öğreniyorum." print re.search("programlama",karakter) <_sre data-blogger-escaped-.sre_match="" data-blogger-escaped-0xb7239918="" data-blogger-escaped-at="" data-blogger-escaped-object="">Gördüğünüz gibi search() metodu "programlama" ifadesini tüm karakter dizisinde aradı ve bulduğu için geriye "eşleşme nesnesi" döndürdü.
Not:match() metodunda bahsettiğimiz eşleşme nesneleri metodları search() metodu içinde geçerlidir.
Not:Düzenli ifadeler sadece karakter dizileri üzerinde işlem yapmamızı sağlar.Listeler, sözlükler gibi yapılar üzerinde doğrudan düzenli ifadeleri kullanamayız.
import re liste = ["python","delphi","c++","c"] re.search("python",liste) Traceback (most recent call last): File "/home/mazlumagar/workspace/Python/deneme.py", line 6, inGördüğünüz gibi program hata verdi. Listeler üzerinde işlem yapmak isterseniz şu şekilde bir kullanım yapabilirsiniz.re.search("python",liste) File "/usr/lib/python2.7/re.py", line 142, in search return _compile(pattern, flags).search(string) TypeError: expected string or buffer
import re liste = ["python","delphi","c++","c"] for i in liste: arama = re.search("python",i) if arama: print arama.group() pythonfindall() Metodu
findall() metodu karakter dizisi içinde aranan öğrenin hepsini bir liste şeklinde geriye döndürür.
import re python ="""Python, nesne yönelimli, yorumlanabilen, birimsel (modüler) ve etkileşimli bir programlama dilidir. Girintilere dayalı basit sözdizimi, dilin öğrenilmesini ve akılda kalmasını kolaylaştırır.Bu da ona söz diziminin ayrıntıları ile vakit yitirmeden programlama yapılmaya başlanabilen bir dil olma özelliği kazandırır. Modüler yapısı, sınıf dizgesini (sistem) ve her türlü veri alanı girişini destekler. Hemen hemen her türlü platformda çalışabilir. (Unix , Linux, Mac, Windows, Amiga, Symbian). Python ile sistem programlama, kullanıcı arabirimi programlama, ağ programlama, uygulama ve veritabanı yazılımı programlama gibi birçok alanda yazılım geliştirebilirsiniz. Büyük yazılımların hızlı bir şekilde prototiplerinin üretilmesi ve denenmesi gerektiği durumlarda da C ya da C++ gibi dillere tercih edilir.""" print re.findall("Python",python); ['Python', 'Python']Gördüğünüz gibi aradığımız "Python" kelimesi kaç tane varsa hepsini liste şeklinde geriye döndürdü. Programı şu hale de getirebiliriz.
kelime = raw_input("Aradığınız kelimeyi giriniz:") print kelime + " karakter dizisinde " , len(re.findall(kelime,python)) , " kere geçmektedir." Aradığınız kelimeyi giriniz:Python Python karakter dizisinde 2 kere geçmektedir.Metakarakterler
Şimdiye kadar kullandığımız düzenli ifadelerde, düzenli ifade ve karakter dizisi arasında doğrudan bir eşleşme yaptık. Bu yaptıklarımız düzenli ifadelerin en temel halidir. Yani "python" düzenli ifadesini karakter dizisinde bulmak için "python" kelimesini kullandık. "python" düzenli ifadesini doğrudan kendisi ile eşleştirmiş olduk. Peki bunları neden söylüyoruz ? Düzenli ifadelerden bu şekilde doğrudan eşleştirme yapmadan da arama yapmamızı sağlayan ifadeler vardır. Zaten düzenli ifadeleri özel kılan bu ifadelerdir.
Bu ifadelere Python'da metakarakterler denir. Aslında biz metakarakterleri daha önceden de kullanmıştık.
print "Python\nGeleceğin programlama dili" Python Geleceğin programlama diliBu örnekte gördüğünüz gibi Python "\n" ifadesini gördüğünde ekrana yazmak yerine yeni satıra geçmesi gerektiğini biliyor. Söylediğimiz gibi "\n" kendisiyle doğrudan eşleşmedi. Aynı şekilde "\t" ifadesini gördüğü zaman "tab" bırakması gerektiğini anlıyor.
print "Python\tGeleceğin programlama dili" Python Geleceğin programlama diliDüzenli ifadeleri düzenli ifade yapan bu metakarakterlerdir. Python bu karakterleri gördüğü zaman doğrudan eşleştirme yapmak yerine farklı tepkiler verecektir. Metakarakterler olmadan düzenli ifadeler ile çok faydalı işler yapmak mümkün değildir.
Python da bulunan metakarakterler:<\br> [ ] . * + ? { } ^ $ | ( )<\br> Şimdi gelin bu karakterleri sırası ile işlemeye başlayalım. Zaten açıkladıkça ne demek istediğimiz anlayacaksınız.
[ ](Köşeli Parantez)
[] metakarakterini açıklamaya çalışmak yerine gelin hemen örnek verelim.
liste = ["özcan demir", "mehmet", "süleyman", "selim", "kemal", "özkan nuri", "esra", "dündar", "esin", "esma", "özhan kamil", "özlem"]Elimizde bu şekilde bir liste olsun. Biz daha önceden gördüğümüz yöntemler ile bu listeden bir öge bulmak istersek, örneğin "özkan", şu şekilde kullanmamız gerekir.
for i in liste: arama = re.search("özkan",i) if arama: print arama.group() özkanEğer arama yapmak istediğimiz öge birden fazla ise biz bu yaptığımızı hepsine tek tek uygulamamız gerekir. İşte tam bu nokta da [] metakarakteri yardımımıza koşuyor.
for i in liste: arama = re.search("öz[ckh]an",i) if arama: print arama.group() özcan özkan özhanİşte sizinde gördüğünüz gibi tek tek hepsine uygulamak yerine değişen kısmı [] ifadesi içine aldık. Python köşeli parantez içinde gördüğü bütün karakterleri tek tek eşleştirme yapacağı karakter dizisine uyguluyor.İlk önce "öz" ile başlayan bütün ögeleri buluyor, ardından "c" harfi ile devam eden ve "an" ile biten ögeyi buluyor. Böylece "özcan" ifadesini bulmuş oldu. Bu yaptığı işlemi [] parantez içindeki bütün karakterlere sırasıyla uyguluyor.
Bu örnekte search() metodunu kullandığımıza dikkat edin. Şimdi gelin match() metodunu kullanarak yeni örnek yapalım.
import re sifre = raw_input("Lütfen şifre oluşturun:") if re.match("[0-9]",sifre): print "Şifre sayı ile başlayamaz." else: print "Şifre başaarıyla oluşturuldu." Lütfen şifre oluşturun:123sifre Şifre sayı ile başlayamaz.Gördüğünüz gibi kullanıcıdan bir şifre istedik ve bu şifrenin sayı ile başlaması durumunda kullanıcıyı uyardık. Burada [0-9] ifadesi sayıları temsil ediyor. Eğer rakam kontrolü yapmak isteseydik [a-z],[A-Z] şeklinde kullanabilirdik.Aynı örneği şu şekilde değiştirebiliriz.
import re sifre = raw_input("Lütfen şifre oluşturun:") if re.match("[0-9, ]",sifre): print "Şifre sayı veya boşluk ile başlayamaz." else: print "Şifre başaarıyla oluşturuldu."[] metakarakterini kullanırken bu örnekte olduğu gibi , ile ayırarak birden fazla kontrol yapabiliyoruz.Son olarak şu şekilde bir örnek verelim
import re karakter ="TY76Z" if re.match("[A-Z][A-Z][0-9]",karakter): print "Aranılan ifade bulundu" else: print "Aranılan ifade bulunamadı" Aranılan ifade bulunduBu örnekte de ilk iki karakterin büyük harf ve onlardan sonra gelen karakterin ise sayı olmasını istediğimizi belirttik.
.(Nokta)
"." metakarakteri yeni satır hariç bütün karakterleri temsil etmek için kullanılır. [] metakarakterinde verdiğimiz örneği değiştirelim.
for i in liste: arama = re.search("öz.an",i) if arama: print arama.group() özcan özkan özhan"." metakarakteri tek bir karakterin yerini tutar. Birden fazla karakteri temsil edemez.
import re liste = ["ali","veli", "ahmet", "hasan"] for i in liste: if re.match(".li",i): print i aliBu örnekte gördüğünüz gibi geriye sadece "ali" ifadesi döndü. "." metakarakteri bir karakter temsil ettiği için "ali" ifadesini buldu. Fakat "Veli" ifadesinde iki karakter olduğu için bulamadı. Birden fazla karakterin yerini tutan metakarakteri daha sonra inceleyeceğiz.
import re numara = raw_input("Okul numaranızı giriniz:") if re.match(".[0-9][a-z][0-9,a-z]",numara): print "Okul numarası kabul edildi." else: print "Okul numarası formata uygun değil" Okul numaranızı giriniz:.8s7 Okul numarası kabul edildi.Bu örnekte kullanıcıdan numara istedik ve gelin bu numaranın koşullarını sıralayalım:
- İlk karakteri herhangi bir karakter olabilir.
- İkinci karakteri sayı olmak zorunda.
- Üçüncü karakteri küçük harf olmak zorunda.
- Dördüncü karakteri sayı veya küçük harf olabilir.
"*" metakarakteri düzenli ifadede konulduğu yerden bir önceki karakteri sıfır veya daha fazla sayıda eşitler. Tanımı biraz karışık ama örnek verince netleşecektir.
#!/usr/bin/env python # -*- coding: utf-8 -*- import re yildiz = ["kd","kod","kood","koood","boş"] for i in yildiz: if re.match("ko*d",i): print i kd kod kood kooodBu örnekteki çıktımızı incelerseniz sadece "*" metakarakterinden bir önceki karakterin adeti değişiyor. İşte sıfır ve daha fazla sayıda eşitler derken kastettiğimiz tam olarak buydu. "*" metakarakteri kendinden önceki sadece bir karakter ile ilgilenir. Yani burada sadece "o" karakterinin sıfır veya daha fazla sayıda bulunup bulunmadığını kontrol eder.
Burada yazdığımız düzenli ifade ile aradığımız ifadenin "k" ile başlamasını sonra sıfır veya daha fazla sayıda "o" ile davam etmesini ve "d" ile bitmesi gerektiğini söylüyoruz.
Şimdi gelin daha önceden öğrendiğimiz "." metakarakteri ile "*" metakarakterini birleştirelim ve bakalım ne olacak?
#!/usr/bin/env python # -*- coding: utf-8 -*- import re liste = ["Ahmet","Mehmet","Muhammet","Ali","Veli","Haşmet"] for i in liste: if re.match(".*met",i): print i Ahmet Mehmet Muhammet HaşmetGördüğünüz gibi "met" ile biten bütün ögeleri listeledi. Hatırlarsanız "." bütün karakterleri temsil ediyordu. "*" ise kendinden önce gelen karakteri sıfır veya daha fazla sayıda eşitliyordu. Yani biz burada şu komutu verdik; bana karakter dizisi başında herhangi bir karakteri ("." ile) sıfır veya daha fazla sayıda içeren ve "met" ile biten ögeleri listele. Bu şekilde "met" ile biten kendisi de dahil olmak üzere her ögeyi listeler.
"*" sayesinde match() metodunu search() metodu gibi de kullanabiliriz. Daha önceden search() ile yaptığımız örneği şu hale getirelim.
import re karakter = "python programlama dilini öğreniyorum." kontrol = re.match(".*programlama",karakter) if kontrol: print "Aranılan öğe bulundu." else: print "Aranılan öğe bulunamadı." Aranılan öğe bulundu.Not: Tabi ki search() metodunu kullanmak performans açısından çok daha iyidir.
+(Artı)
"+" metakarakteri "*" metakarakterine oldukça benzerdir. "*" kendisinden önceki sıfır veya daha fazla sayıda tekrar eden karakterleri ayıklıyordu."+" ise kendisinden önceki bir veya daha fazla sayıda tekrar eden karakteri ayıklar.
"*" metakarakterini işlerken verdiğimiz örneği hatırlarsanız, "kd" ögesini de çıktı olarak alıyorduk. Biz her zaman böyle olmasını istemeyebiliriz. Aradığımız karakterin öge içinde en az bir kere geçmesini istediğimiz durumlarda "*" yerine "+" metakarakterini kullanmalıyız.
import re arti = ["kd","kod","kood","koood","boş"] for i in arti: if re.match("ko+d",i): print i kod kood kooodGördüğünüz gibi bu sefer "kd" ögesi geriye dönmedi.
Hatırlarsanız [] metakarakterini işlerken şöyle bir örnek vermiştik.
import re karakter ="TY76Z" if re.match("[A-Z][A-Z][0-9]",karakter): print "Aranılan ifade bulundu" else: print "Aranılan ifade bulunamadı"Burada aradığımız ifadenin ilk iki ögesinin büyük harf olmasını belirtmek için iki kere [A-Z] ifadesini kullandık. Ama şimdi "+" metakarakterini öğrendiğimize göre şu hale getirebiliriz.
import re karakter ="TYS76Z" if re.match("[A-Z]+[0-9]",karakter): print "Aranılan ifade bulundu" else: print "Aranılan ifade bulunamadı" Aranılan ifade bulunduİlk örneğimizde aranılan ifadenin ilk iki karakterinin büyük harf sonraki karakterin ise sayı olması gerekir. Ama "+" metakarakterini kullanarak yaptığımız örnekte bu sınırlama ortadan kalktı. Bir veya birden fazla sayıda büyük harf olabilir.
?(Soru İşareti)
Önceki bölümlerde işlediğimiz "*" metakarakteri eşleşmenin sıfır veya daha fazla olduğu durumlarda "+" metakarakteri ise eşleşmenin bir veya daha fazla olduğu durumlarda kullanılıyordu. "?" metakarakteri ise eşleşme sayısının sıfır veya bir olduğu durumlarda kullanılır.
Daha önce yaptığımız örneğin üç metakarakter ile kullanımını gösterelim ki aradaki farkı net bir biçimde görelim.
import re yildiz = ["kd","kod","kood","koood","boş"] for i in yildiz: if re.match("ko*d",i): print i kd kod kood koood import re arti = ["kd","kod","kood","koood","boş"] for i in arti: if re.match("ko+d",i): print i kod kood koood import re soru = ["kd","kod","kood","koood","boş"] for i in soru: if re.match("ko?d",i): print i kd kodGördüğünüz gibi "?" çıktı olarak sıfır ve bir karakter barındıran "kd" ve "kod" ifadelerini geriye döndürdü.
{}(Küme Parantezi)
{} merakarakteri sayesinde bir eşleşmenin kaç adet olması gerektiğini belirtebiliyoruz.
#!/usr/bin/env python # -*- coding: utf-8 -*- import re kume = ["kd","kod","kood","koood","boş"] for i in kume: if re.match("ko{2}d",i): print i koodGördüğünüz gibi, biz küme parantezini kullanarak "o" karakterinin iki adet olmasını istediğimizi belirttik. Python da bize sadece "kood" ifadesini döndürdü.
{} küme parantezinin bir başka kullanım şekli ise; bir karakterin en az ve en çok kaç kere tekrar etmesi gerektiğini söyleyebiliyoruz. Hemen örneğine bakalım.
for i in yildiz: if re.match("ko{0,2}d",i): print i kd kod koodBu sefer Python bize "o" karakterinin hiç olmadığı durumdan 2 adet olduğu duruma kadar geri döndürmüş oldu.
liste = ['23BH56','TY76Z','4Y7UZ','TYUDZ','34534','1agAY54'] for i in liste: a=re.search("[A-Z].[0-9]",i) if a: print a.group()^(Şapka)
Hatırlarsanız daha önceki konularda match() ve search() metodlarını işlemiştik. match() metodu arama yaparken ifadenin sadece başına bakar search() metodu ise aranılan ifadeyi tüm öge içinde arardı.
^ metakarakteri ile ise search() motodu ile arama yaparken match() metodu gibi ifadenin sadece başına bakmasını istediğimizi belirtiyoruz.
import re liste = ['23BH56','TY76Z','4Y7UZ','TYUDZ','34534','1agAY54'] for i in liste: a=re.match("[A-Z]+[0-9]",i) if a: print i TY76ZBurada Python'a aradığı öge için şu koşulu belirttik; aradığın öge bir veya daha fazla sayıda büyük harf ile başlayacak ve onları bir sayı takip edecek. Python'da bu koşula göre bize çıktı verdi. Burada dikkat etmeniz gereken match() metodunu kullanmış olmamız. Şimdi aynı örneği search() metodu ile kullanalım.
for i in liste: a=re.search("[A-Z]+[0-9]",i) if a: print i 23BH56 TY76Z 4Y7UZ 1agAY54Gördüğünüz gibi çıktı sayımız bir hayli arttı. match() metodu eşleştirme yaparken ifadenin sadece başına bakıyor search() metodu ise tüm ifade içinde eşleştirme yapıyordu. Şimdi aynı örnekte search() metodunu "^" metakarakteri ile beraber kullanalım.
for i in liste: a=re.search("^[A-Z]+[0-9]",i) if a: print i TY76ZGördüğünüz gibi search() metodundaki çıktının aynısını aldık. Biz burada yazdırma işlemi yaparken listenin elemanını yazdırıyoruz. Şu şekilde eşleştirme nesnesi ile dönen ifadeyi yazdıralım.
for i in liste: a=re.search("[A-Z]+[0-9]",i) if a: print a.group() BH5 TY7 Y7 AY5Bu sefer bize sadece aradığımız ögeyi geriye döndürdü. Eğer biz burada tüm ifadeyi döndürmesini istersek şu şekilde kullanabiliriz.
for i in liste: a=re.search(".*[A-Z]+[0-9].*",i) if a: print a.group() 23BH56 TY76Z 4Y7UZ 1agAY54Gördüğünüz gibi tüm ifadeyi geriye döndürmüş olduk.
"^" metakarakterinin bir görevi daha vardır. Hariç anlamında da kullanılır. Yani arama işlemi yaparken belli bir koşula uyan ifadeleri almak istemeyebiliriz. Bu durumlarda da "^" metakarakterini kullanabiliriz.
for i in liste: nesne = re.match("[0-9A-Z][^0-9]",i) if nesne: print i 4Y7UZ TYUDZ 1agAY54Burada ifadenin harf veya sayı ile başlamasını ondan sonra ise sayı gelmemesini söyledik. Python da bize ona göre çıktı vermiş oldu.
$(Dolar)
"$" metakarakteri bir önceki bölümde incelediğimiz "^" metakarakterinin tam tersi işi yapar. "^" karakteri ile karakter dizilerinin nasıl başlayacağını belirtiyorduk. "$" metakarakteri ile de nasıl biteceğini belirtiyoruz.
Elimizde şu şekilde bir isim listesi olsun ve biz bu listeden ismi "an" ile bitenleri ayıklayalım.
liste = ['Hasan','ayşe','ahmet','Alkan','esra','Alıngan','Altan','veli'] for i in liste: if re.search('an$',i): print i Hasan Alkan Alıngan AltanGördüğünüz gibi çıktılar tamda beklediğimiz gibi oldu.
Not: Burada önemli olan "^" ve "$" metakarakterlerini search() metodu ile kullanmanız gerektiğidir. Eğer match() metodu ile kullanırsanız herhangi bir çıktı alamazsınız.
Ters Bölü
"\" işareti daha önceden de bildiğimiz kaçış dizisidir. Şimdiye kadar işlediğimiz metakarakterler kendileri ile eşleşmiyorlar. Yani bu metakarakterleri bir karakter dizisinde aramak istesek özel anlamları yüzünden bu mümkün olmayacaktır. İşte bu özel anlamlarını iptal edip bu karakterleri Python'a normak karakter gibi göstermek için "\" kaçış dizisini kullanıyoruz.
import re liste = ['2+5','3*4','4/2','6+9','7+5','5-2'] for i in liste: if re.match('[0-9]+/',i): print i 4/2Örneği açıklayalım. Biz burada Python'a aradığın öge sayı ile başlayacak, bu sayı bir veya daha fazla sayıda olabilir(+ metakarakteri) ve sonra / (Buradaki normal bölü işaretidir.) devam edecektir. Python da bu koşula uyan tek karakter dizisini bize döndürdü. Dikkat ederseniz buradaki "+" karakteri metakarakterdir yani özel bir anlamı vardır. Kendisinden önceki sayının bir veya daha fazla sayıda olabileceğini belirtiyor. Ama biz liste içinde sadece toplama (+) işlemi olan ögeleri getirmek isteseydik ne yapmamız gerekiyordu ? Örneğimize bakalım.
liste = ['2+5','3*4','4/2','6+9','7+5','5-2'] for i in liste: if re.match('[0-9]+\+',i): print i 2+5 6+9 7+5Gördüğünüz gibi sadece toplama işlemi olan ögeleri ayıkladık. "\" işareti ile kendisinden sonra gelen "+" metakarakterinin özel anlamını elinden almış olduk. Yani sıradan bir karakter haline getirdik. Burada kullandığımız işaretin bölü(/) işareti olmadığına dikkat edin. Eğer bölü işaretini kullanırsanız ilk ifadedeki çıktıyı elde ederiz.
for i in liste: if re.match('[0-9]+/+',i): print i 4/2Burada "+" metakarakteri özel anlamını yitirmedi. Yani biz bir veya daha fazla sayıda bölü (/) işareti ara demiş olduk.
|(Dik Çizgi)
"|" metakarakteri "veya" anlamına gelir. Birden fazla eşleştirme kalıbı kullanılmak istenen durumlarda kullanılır.
Bir önceki başlıkta verdiğimiz örnek üzerinden gidelim.
liste = ['2+5','3*4','4/2','6+9','7+5','5-2'] for i in liste: if re.match('[0-9]+\*|[0-9]+\-',i): print i 3*4 5-2Bu örnekte gördüğünüz gibi iki ifadenin kalıbını "|" metakarakteri ile ayrı ayrı oluşturduk. Python da ikisine birden uyanı bize getirdi. Burada "\" kaçış dizisini kullanarak ilk önce sayı ile başlayan ve "*" ile devam edenleri veya sayı ile başlayan "-" ile devam edenleri getir demiş olduk.
Elimizdeki bir listede herhangi bir ögenin kendisini yazıyorsak da bu metakarakteri kullanabiliriz.
re.search("Galatasaray" | "Fenerbahçe" | "Beşiktaş")() (Parantez)
"()" metakarakteri düzenli ifade kalıplarını gruplamamızı sağlar. Bu metakarakter sayesinde bir karakter dizisinin istediğimiz bölümlerini çok rahat bir şekilde ayıklayabiliriz.
İleride eşleşme nesneleri metotlarından group() metodunu işlerken örnekler vereceğiz.
Bunların hepsini çok iyi bilmek gerekiyor mu işe lazım oldukça bakılabilir gibi geldi.Yoksa çok fazla akılda kalmaz.
YanıtlayınSilhaklısın
SilFaydalı bir paylaşım çok teşekkürler..
YanıtlayınSil