Başlangıç > Dökümanlar > Python’da düzenli ifadeler

Python’da düzenli ifadeler

Python’da düzenli ifadeler sözdiziliminde normal karakterler(A,a,0) gibi ve bir takım özel karakterler kullanılır.
Python’da kullanılan özel karakterler:
. ^ $ * + ? {} [ ] \\ | ( )
Şimdi bu karakterlerin ne işe yaradıklarını örnekleri ile beraber inceleyelim.

. Karakteri:
.(Nokta) karakteri yeni satır ifadesi(\\n) hariç herhangi bir karaktere eşleme yapmak için kullanılır. re.DOTALL ile birlikte kullanıldığında yeni satır ifadesi dahil herhangi bir karaktere eşleme yapabilir.

>>> import re
>>> re.match(".","a").group()
’a’
>>> re.match(".","1").group()
’1’
>>> re.match(".","A").group()
’A’
>>> re.match(".","-").group()
’-’
>>> re.match(".","*").group()
’*’
>>> re.match(".","\\n",re.DOTALL).group()
’\\n’
>>> re.match(".","\\n").group()
Traceback (most recent call last):
File "<pyshell#15>", line 1, in -toplevel-
re.match(".","\\n").group()
AttributeError: ’NoneType’ object has no attribute ’group’

Üstteki örnekteki hatanın sebebi şu. re.match() metodu eşleme yaptığında bir match nesnesi döndürürken eşleme yapılmadığında None döndürür. Burada da “\\n” ile eşleme yapılmadığı için None döndürdü ve group() methodu match nesnesinin metodur None group() methodunu kullanmadığı Python için bu hatayı verir.

^ Karakteri:
^ Karakteri kendinden sonra gelen karakteri kelime başında arar. re.MULTILINE ile kullanıldığında karakter dizisinin en başına ve yeni satır ifadesinden sonraki karaktere eşleme yapar. Bu ifade köşeli parantezler içinde kullanıldığında kendinden sonra gelen karakterler hariç her karaktere eşleme yapılacak anlamına gelir.

>>> re.findall(".","ab\\nc\\nd",re.MULTILINE)
[’a’, ’b’, ’c’, ’d’]
>>> re.findall("^.","ab\\nc\\nd",re.MULTILINE)
[’a’, ’c’, ’d’]
>>> re.match("[^abc]*","def").group()
’def’

Örnektede görüldüğü gibi ilk denemede “.” yeni satır ifdesi hariç bütün karakterlere eşlendi ancak ikinci denemede sadece satır başındakine ve yeni satır ifadesinden sonrakilere eşleme yapıldı.

$ Karakteri:
$ karakteri kelimenin en sonuna eşleme yapar. Kendinden önce gelen karakteri satır sonundan itibaren eşler. re.MULTILINE ile kullanıldığında her yeni satır ifadesinin öncesine ve tüm karakter dizsinin en sonuna eşleme yapar.

>>> re.findall(".$","abc\\ndef\\nghk",re.MULTILINE)
[’c’, ’f’, ’k’]
>>> re.findall(".$","abc\\ndef\\nghk")
[’k’]

* Karakteri:
* karakteri kendinden önceki karakterin 0 yada varsa daha fazla sayıdaki tekrarına eşleme yapar.

>>> re.match("n*.","e").group()
’e’
>>> re.match("n*.","ne").group()
’ne’
>>> re.match("n*.","nnne").group()
’nnne’

+ Karakteri:
+ karakteri kendinden önce gelen karakterin en az bir yada varsa daha fazla tekrarına eşleme yapar.

>>> re.match("n+.","ne").group()
’ne’
>>> re.match("n+.","nne").group()
’nne’
>>> re.match("n+.","e").group()

Traceback (most recent call last):
File "<pyshell#56>", line 1, in -toplevel-
re.match("n+.","e").group()
AttributeError: ’NoneType’ object has no attribute ’group’

Yukarıdaki hatanın sebebi “+” karakterinin en az bir tane “n” karakterine eşleme yapmak istemesi. Eşleme olmadığı için match() methodu None döndürüyor.

? Karakteri:
? karakteri kendinden önce gelen karakterin 0 yada varsa 1 kez tekrarına eşleme yapar.

>>> re.match("n?.","e").group()
’e’
>>> re.match("n?.","ne").group()
’ne’
>>> re.match("n?.","nne").group()
’nn’

{m} İfadesi:
a{m} ifadesi ile eşleme yapılabilmesi için a’nın eşleştirilecek karakter dizisinde m kez tekrarlanmış olması gerekir.

>>> re.match("n{5}","nnnnn").group()
’nnnnn’
>>> re.match("n{5}","nnnn").group()

Traceback (most recent call last):
File "<pyshell#62>", line 1, in -toplevel-
re.match("n{5}","nnnn").group()
AttributeError: ’NoneType’ object has no attribute ’group’
>>> re.match("n{5}","nnnnnn").group()
’nnnnn’

{m,n} İfadesi:
a{2,5} ifadesi a’nın en az 2 en çok 5 kere tekrarlanmış olduğu karaker dizisine eşleme yapar. Eğer ifade a{2,} şeklinde olursa en az iki “a” karakterine varsa daha fazlasına eşleme yapar.

>>> re.match("n{2,5}","nn").group()
’nn’
>>> re.match("n{2,5}","nnn").group()
’nnn’
>>> re.match("n{2,5}","nnnnnn").group()
’nnnnn’
>>> re.match("n{2,}","nnnnnn").group()
’nnnnnn’

{0,} ifadesi * karakterinin yaptığını
{1,} ifadesi + karakterinin yaptığını
{0,1} ifadesi ? karakterinin yaptığını yapar ama * + ? işaretlerini kullanmak kısa ve okunur olması bakımından daha mantıklıdır.

{m,n}? İfadesi:
a{2,5}? ifadesi eşlenecek karakter dizisinin içindeki a’nın mümkün olan en az tekrarına eşleme yapar. Aşağıdaki örneklerde a{2,5}? ifadesinden sonra gelen ifadelerin durumu nasıl etkilediğine dikkat ediniz.

>>> re.match("n{2,5}?","nnnnnn").group()
’nn’
>>> re.match("a{2,5}?b?c?","aaaaabc").group()
’aa’
>>> re.match("a{2,5}b?c?","aaaaabc").group()
’aaaaabc’
>>> re.match("a{2,5}b*c*","aaaaabc").group()
’aaaaabc’
>>> re.match("a{2,5}?b*c*","aaaaabc").group()
’aa’

*?,+?,?? İfadeleri:
*?,+?,?? ifadeleri *,+ ve ? ifadelerinin normalde eşlendiği tekrarın mümkün olan minumum sayıda olanına eşleme yapılmasını sağlar. Aşağıdaki örneklerde ifadenin devamının duruma nasıl etki ettiğine dikket ediniz.

>>> re.match("n*","nnnnnn").group()
’nnnnnn’
>>> re.match("n*?","nnnnnn").group()
’’
>>> re.match("n+","nnnnnn").group()
’nnnnnn’
>>> re.match("n+?","nnnnnn").group()
’n’
>>> re.match("<.?>","<>>").group()
’<>>’
>>> re.match("<.??>","<>>").group()
’<>’
>>> re.match("n*?a","nnnnnna").group()
’nnnnnna’
>>> re.match("n*?a?","nnnnnna").group()
’’

[] Karakterleri:
Köşeli parantezler bir karakter grubu belirtmek için kullanılır. Bu karakter grupları köşeli parantezler içine tektek yazılabildiği gibi "-" işareti kullanılarakta karakter grubu da belirtilebilir. Mesela [a-z] a ile z arasındaki karakterler gurubunu ifade eder. Köşeli parantezler içinde ^ kullanımı kendinden sonra gelenler hariç herşeye eşleme yapılacak anlamına gelir. Yani [^abc] abc hariç herşey.

>>> re.match("[abc]","ac").group()
’a’
>>> re.match("[abc].","ac").group()
’ac’
>>> re.match("[^abc].","zac").group()
’za’
>>> re.match("[a-z]*","def").group()
’def’

\\ Karakteri:
Bu karakter sonrasında kullanılan bazı karakterler ile özel karakter dizilerini işaret eder.(\\w,\\W\\,\\s,...) Aynı zamanda \\ karakterini bütün düzenli ifade özel karakterleleri için kaçış karakteri olarak kullanılabilir. Mesala "[" yada "\\" karakterlerini eşleştirme için kullanmayı düşündüğünüzde bunların özel karakter olarak algılanmasını önlemek için "\\[", "\\\\" şeklinde kullanılmasını örnek olarak verebiliriz.
\\ karakterini eşleme işlemlerinde kullanmaya kalktığımızda biraz başımız ağırabilir.
Mesela "\\neset" kelimesine bir eşleme yazacağımızı düşünelim.

>>> print re.match("\\neset","\\neset").group()

eset
>>>

Görüldüğü üzere örnek ifadede(pattern) ve kelimede \\n yeni satır olarak algılanıyor. Değiştirelim:

>>> print re.match("\\\\neset","\\\\neset").group()

Traceback (most recent call last):
File "<pyshell#38>", line 1, in -toplevel-
print re.match("\\\\neset","\\\\neset").group()
AttributeError: ’NoneType’ object has no attribute ’group’

Yine olmadı. Çünkü bu seferde re \\\\neset(pattern) ifadesindeki ilk \\ karakterini diğer \\ karakterine kaçış olarak algıladı ve “\\neset” şeklinde yorumladı buradaki “\\n” artık yeni satır demek. Ama bizim istediğimiz bu değil.

>>> re.match("\\\\neset","\\neset").group()
’\\neset’
>>> print re.match("\\\\\\\\neset","\\\\neset").group()
\\neset

Bu sefer tamam ama gördüğünüz gibi bu iş baya karmaşık bir hal aldı. Peki ne yaparsak bundan kurtuluruz. Bundan kurtulmanın yolu raw string kullanmak. "\\n" normalde yeni satır olarak algılanırken r"\\n" ile \\ ve n karakterleri olarak yorumlanır. O zaman örneğimizi bir daha yazalım.

>>> print re.match(r"\\\\neset",r"\\neset").group()
\\neset

Sizcede daha kolay değil mi?

| Karakteri:
Bu karakter veya anlamında kullanılır. Diyelim ki bir kelime içinde A karakterini yoksa B karakterini eşleştireceğiz o zaman A|B şeklinde bir kullanımla işimiz halledebiliriz. Böylece | karakterinin önündeki yada arkasındaki eşlenecek demiş oluruz.
Bu karakteri “\\|” şeklinde yada [|] ifadesindeki gibi köşeli parantezler içinde verirsek özel karakter olarak algılanmayacaktır.

>>> re.match("a|b","ab").group()
’a’
>>> re.match("a|b","ba").group()
’b’
>>>
>>> re.match("\\|","|").group()
’|’
>>> re.match("[|]","|").group()
’|’

(...) İfadesi:
(...) ifadesi ile bir grup tanımlanabilir. Düzenli ifadelerde gruplar 1 den başlayarak numaralandırırlır. \\sayi şeklinde bir ifadedeki sayı grubun numarasını işaret eder. “(“ veya “)” karakterlerini özel karakter olarak kullanmak istemediğimiz zaman “\\(“,”\\)” yada [(],[)] şeklinde belirtebiliriz.

>>> re.match(r"(nes)",r"nesnes").group()
’nes’
>>> re.match(r"(nes)\\1",r"nesnes").group()
’nesnes’
>>> re.match(r"(nes)(et)\\1\\2",r"nesetneset").group()
’nesetneset’

(?iLmsux) İfadesi:
Düzenli ifadelerde kullanılan re.I,re.L,re.M,re.S,re.U,re.X (flags) ifadelerinin bir yada daha fazlasını ayarlamak için kullanılır. Mesela düzenli ifadelerde büyük küçük harf ayrımını ortadan kaldırmak için re.INGNORECASE kullanılır. Bu ifadenin kullanılması ile (?i) aynı işi yapar.

>>> re.match("a","A").group()

Traceback (most recent call last):
File "<pyshell#162>", line 1, in -toplevel-
re.match("a","A").group()
AttributeError: ’NoneType’ object has no attribute ’group’
>>> re.match("a","A",re.IGNORECASE).group()
’A’
>>> re.match("(?i)a","A").group()
’A’
>>> re.match("(?i)a*","Aa").group()
’Aa’
>>> re.match("(?i)a*","AaA").group()
’AaA’

(?:...) İfadesi:
Bu ifade düzenli ifadelerin grup olarak algılanmayan versiyonudur. Eşleme sonrası grup olarak döndürülmesinin istenmediği yada sonraki ifadeye referans olmasının istendiği durumlarda kullanışlıdır.

>>> re.match("(linux)*","linuxlinuxlinux").groups()
(’linux’,)
>>> re.match("(?:linux)*","linuxlinuxlinux").groups()
()
>>> re.match("(?:linux)","linuxlinuxlinux").group()
’linux’
>>> re.match("(?:linux)*","linuxlinuxlinux").group()
’linuxlinuxlinux’

(?P<isim>...) İfadesi:
Bu ifade () ifadesi ile aynı işi yapar farklı olarak gruba bir isim vermemizi sağlar. Bu isim ile düzenli ifadelerin değişik yerlerinde grubu tekrar kullanabiliriz. Verilen isim pythondaki değişken isimleri kurallarına uymalıdır.

>>> re.match("(?P<id>[0-9]*)([a-z]*)","123456789linux").group()
’123456789linux’
>>> re.match("(?P<id>[0-9]*)([a-z]*)","123456789linux").groups()
(’123456789’, ’linux’)
>>> re.match("(?P<id>[0-9]*)([a-z]*)","123456789linux").group(1,2,1)
(’123456789’, ’linux’, ’123456789’)
>>> re.match("(?P<id>[0-9]*)([a-z]*)","123456789linux").group("id",2,"id")
(’123456789’, ’linux’, ’123456789’)
>>> re.match("(?P<id>[0-9]*)([a-z]*)","123456789linux").groupdict()
{’id’: ’123456789’}

(?P=isim) İfadesi:
Daha önce isimlendirdiğimiz grubu çağırmak için kullanacağımız ifade.

>>> re.match("(?P<id>[0-9]*)([a-z]*)(?P=id)","123456789linux123456789").group()
’123456789linux123456789’

(?#...) İfadesi:
Bu bir açıklamayı işaret eder ve görmezden gelinir.

>>> re.match("(?P<id>[0-9]*(?# Sayılardan oluşan id isimli grubum))",
* "123456789"
* ).group()
’123456789’

(?=...) İfadesi:
Bu ifadede belirtilenler kendinden öncekinin devamında varsa eşleştirme yapılır. Yoksa yapılmaz. Eşleşme yapıldığında ise bu ifade içinde belirtilen döndürülmez.

>>> re.match("neset(?=özkan)","nesetözkan").group()
’neset’
>>> re.match("neset(?=özkan)","neset").group()

Traceback (most recent call last):
File "<pyshell#209>", line 1, in -toplevel-
re.match("neset(?=özkan)","neset").group()
AttributeError: ’NoneType’ object has no attribute ’group’

(?!...) İfadesi:
Bu ifadede belirtilenler kendinden öncekinin devamında varsa eşleştirme yapılmaz. Yoksa kendinden öncekine eşleme yapılır.

>>> re.match("neset(?!özkan)","neset").group()
’neset’
>>> re.match("neset(?!özkan)","nesetözkan").group()

Traceback (most recent call last):
File "<pyshell#211>", line 1, in -toplevel-
re.match("neset(?!özkan)","nesetözkan").group()
AttributeError: ’NoneType’ object has no attribute ’group’

(?<=...) İfadesi:
Bu ifade içinde belirtilenin sonrasına ifadenin devamındaki eşlenir. İfade içindeki tanımlama net uzunluk belirtmelidir. *a yada a{3,5} gibi ifadeler kabul edilmez. Hiç bir zaman karakter dizisinin başına eşleme yapmaz. search() metodu ile kullanımı uygundur.

>>> re.search("(?<=abc)def","abcdef").group()
’def’
>>> re.search(r"(?<=a|b)def","bdef").group()
’def’

(?<!...) İfadesi:
İfade içinde belirtilene eşleme yapılmadığı takdirde devamına eşleme yapılır. Aksi durumda eşleme yapılmaz. Kesin uzunluklar belirtilen ifadeler kabul eder. a*, a{2,3} gibi ifadeler kullanmaya izin vermez.

>>> re.search(r"(?<!a|b)def","bdef").group()

Traceback (most recent call last):
File "<pyshell#221>", line 1, in -toplevel-
re.search(r"(?<!a|b)def","bdef").group()
AttributeError: ’NoneType’ object has no attribute ’group’
>>> re.search(r"(?<!a|b)def","cdef").group()
’def’

(?(id/name)yes-pattern|no-pattern) İfadesi:
Bu ifadede ile belirtilen gruba daha önceden eşleme yapılmışsa yes-pattern kısmındaki şablon yapılmamışsa no-pattern kısmındaki şablon eşlenmeye çalışılır. no-pattern isteğe bağlıdır kullanmaya biliriz.

>>> re.match("(<)?(\\w+@\\w+(?:\\.\\w+)+)(?(1)>)","isim@host.com").group()
’isim@host.com’
>>> re.match("(<)?(\\w+@\\w+(?:\\.\\w+)+)(?(1)>)","<isim@host.com>").group()
’<isim@host.com>’
>>> re.match("(<)?(\\w+@\\w+(?:\\.\\w+)+)(?(1)>)","isim@host.com>").group()
’isim@host.com’
>>> re.match("(<)?(\\w+@\\w+(?:\\.\\w+)+)(?(1)>)","<isim@host.com").group()

Traceback (most recent call last):
File "<pyshell#226>", line 1, in -toplevel-
re.match("(<)?(\\w+@\\w+(?:\\.\\w+)+)(?(1)>)","<isim@host.com").group()
AttributeError: ’NoneType’ object has no attribute ’group’

\\ karakteri ile belirtilen özel ifadeler:
\\sayi ifadesi:
sayi yerine verilen grup numarasına eşleme yapar. Gruplar 1 den başlayarak numaralandırılır. Örnek olarak (.+) \\1 ifadesi “ve ve” yada “55 55” ile eşleme yapabilir. \\sayi ifadesi 1 den 99 kadar olan grupların eşleşmesinde kullanılabilir. \\sayi özel ifadesini kullanırken raw string kullanmaya dikkat etmek gerekir.r”(1+) \\1” gibi.

>>> re.match(r"(a)(b)\\2","abb").group()
’abb’
>>> re.match(r"(a)(b)\\1","aba").group()
’aba’

\\A ifadesi:
Sadece karakter dizisinin başına eşleme yapar.

>>> re.findall("\\Ai","iki")
[’i’]
>>> re.findall("i","iki")
[’i’, ’i’]

\\b ifadesi:
Kelimenin başına yada sonuna (sınırlarına) eşleme yapar.

>>> re.search(r"\\bbir\\b","bu bir denemedir.").group()
’bir’
>>> re.search(r"\\bbir\\b","bu birinci denemedir.").group()

Traceback (most recent call last):
File "<pyshell#257>", line 1, in -toplevel-
re.search(r"\\bbir\\b","bu birinci denemedir.").group()
AttributeError: ’NoneType’ object has no attribute ’group’

\\B İfadesi:
Bu ifade bir kelime içindeki bir yere eşleme yapabilir. Kelimenin başlangıcına ve sonuna(sınırlarına) eşleme yapmaz.

>>> re.findall("\\Bkar\\B","Ankara’da kar yağıyor")
[’kar’]
>>> re.findall("kar","Ankara’da kar yağıyor")
[’kar’, ’kar’]

\\d İfadesi:
Bu ifade 0-9 arasındaki sayılara eşleme yapar. [0-9] ifadesi ile aynıdır. Eğer re.UNICODE ile kullanılırsa Unicode karakter özellikleri veritabanında sayı olarak işaretlenmiş olan karakterlere eşleme yapar.

\\D İfadesi:
Bu ifade 0-9 arasındaki sayılar hariç her karaktere eşleme yapar. [^0-9] ifadesi ile aynıdır. Eğer re.UNICODE ile kullanılırsa Unicode karakter özellikleri veritabanında sayı alarak işaretlenmiş olan karakterlerin dışındaki karakterlere eşleme yapar.

\\s İfadesi:
Bu ifade boşluklara eşleme yapar. [ \\t\\n\\r\\f\\v] ifadesi ile aynıdır. Eğer re.LOCALE ile kullanılırsa bunlarla birlikte yerelde boşluk olarak tanımlı olan her karaktere, re.UNICODE ile kullanılırsa [ \\t\\n\\r\\f\\v] ifadesinde tanımlananlara ve Unicode karakter özellikleri veritabınında boşluk olarak belirlenmiş karakterlere eşleme yapar.

\\S İfadesi:
Bu ifade boşluk olmayan her karaktere eşleme yapar. [^ \\t\\n\\r\\f\\v] ifadesi ile aynıdır. re.LOCALE ile bunlara ek olarak yerelde boşluk olarak tanımlanmamış her karaktere re.UNICODE ile yine bunlara ve Unicode karakter özellikleri veritabanında boşluk olarak tanımlanmamış her karaktere eşleme yapar.

\\w İfadesi:
Bu ifade alfanumerik karakterlere ve altcizgi ”_” karakterine eşleme yapar. [a-zA-Z0-9_] ifadesine eşttir. re.LOCALE ile [0-9_] karakter dizisine ek olarak yerelde alfanumerik olarak tanımlanmış bütün karakterlere re.UNICODE ile kullanıldığında [0-9_] karakter dizisine ve Unicode karakter özellikleri veritabanında alfanümerik olarak tanımlanmış olan her karakter eşleme yapar.

\\W İfadesi:
Bu ifade alfanumerik olmayan her karaktere eşleme yapar. [^a-zA-Z0-9_] ifadesine eşttir. re.LOCALE ile kullanımda [0-9_] karakter dizisi dışında kalanlarla birlikte yerelde alfanumerik olarak tanımlanmamış her karaktere re.UNICODE ile birlikte ise yine [0-9_] karakter dizisinin dışında kalanlar ile Unicode karakter özellikleri veri tabanında alfanumerik olarak tanımlanmamış her karaktere eşleme yapar.

\\Z İfadesi:
Sadece karakter dizisinin sonuna eşleme yapar.

>>> re.search(r".\\Z",r"linux").group()
’x’

PYTHON’DA DÜZENLİ İFADELERİN KULLANIMI:
Buraya kadar re sözdiziliminin açıklamasını yapmaya çalıştım. Şimdi düzenli ifadelerin Python’da nasıl kullanıldığına bakalım. Python’da düzenli ifadeleri kullanmamızı sağlayacak modül re modülüdür. re modülü bize aşağıdaki fonksiyonları sağlar.

compile(pattern,flags)
match(pattern,string,flags)
search(pattern,string,flags)
findall(pattern,string,flags)
finditer(pattern,string,flags)
split(pattern,string,maxsplit=0)
sub(pattern,repl,string,count)
subn(pattern,repl,string,count)

Bu fonksiyonları derlenmiş düzenli ifade nesnesi adlı konuda ayrıntıları ile inceleyeceğiz.

IGNORECASE
LOCALE
MULTILINE
DOTALL
UNICODE
VERBOSE

Bu tanımlamalar yukarıda sıraladığım fonksiyonların flags parametresi tarafından kullanılır. Şimdi bunları ayrıntılı olarak inceleyelim.

I
IGNORECASE:
Normal şartlarda düzenli ifadelerde büyük küçük harf ayrımı vardır. Eşleştirme işlemlerinde büyük küçük harf ayrımı yapılmamasını sağlamak için I yada IGNORECASE kullanır.

L
LOCALE:

\\w,\\W,\\b,\\B,\\s,ve \\S ile belirtilen karakter grublarının yerele bağlı olması sağlanır

M
MULTILINE:
^ özel karakterinin her zaman karakter disinin başına eşleme yaptığını $ özel karakterinin de her zaman karakter dizisinin sonuna eşleme yaptığını belirtmiştik. Bu özel karakterlerin M yada MULTILINE kullanarak verilen karakter dizisindeki her satır için bu eşlemeleri yapması sağlanır.
S
DOTALL:
. özel karakteri normal şartlarda yeni satır ifadesi hariç her karaktere eşleme yapar. S yada DOTALL kullanıldığında yeni satır ifadesi dahil her karaktere eşleme yapılır.

U
UNICODE:

\\w, \\W, \\b, \\B, \\d, \\D, \\s ve \\S özel karakterlerinin belirttiği karakter gruplarının unicode karakter özellikleri veritabanına bağlı olmasını sağlar.

V
VERBOSE:
Bu ifadenin değişik etkileri vardır. Boşuk karakterleri karakter grubu belirten işaretler içinde “[]” değilse yada önünde kaçış yapılmamış “\\” karakteri yoksa görmezden gelinir.
# karakteri karakter grubu belirten “[]” karakterleri içinde değilse ve önünde kaçış yapılmamış “\\” karakteri yoksa # karakterinden satır sonuna kadar olan herşey açıklama olarak kabul edilir. Böylece okunması çok zor olan düzenli ifadeleri daha okunur bir şekilde yazma imkanımız olur.

Bu tanımlamaların birkaçını aynı anda kullanmak için aralarına “|” karakterini koymak gerekir.

>>> p=re.compile(r"""
[#]*# # karakterine eşleme yap
\\d+*# sayıları eşle
*# boşluk görmezden gelinecek dikkat edin
test*# test karakterine eşleme yap
""",
* re.VERBOSE
* )
>>> p.match("#123456test").group()
’#123456test’

DERLENMİŞ DÜZENLİ İFADE NESNESİ:
re modülü compile fonksiyonu ile bize düzenli ifade şablonunu derleme imkanı verir. Re modulu içindeki match,search,findall,finditer,split,sub,subn fonksiyonları derlenmiş düzenli ifadesinin metodlarında da mevcut ve bunlar aynı işi yaparlar.

compile(pattern,flags):

>>> import re
>>> pat=re.compile("ab*")
>>> print pat
<_sre.SRE_Pattern object at 0x404829f8>

Yukarıda görüldüğü gibi düzenli ifade şablonunu(pattern) derleyerek derlenmiş düzenli ifade nesnesi(Regular Expression object) elde etmiş olduk. Artık bu nesnenin sahip olduğu bütün metodlarıda kullanabiliriz.

re.compile() bize opsiyonel olan flag adı altında bazı parametreler kullanmamıza imkan tanır. Bu parametrelerin neler olabileceğine yazının önceki kısmında anlatmıştık.

>>> pat=re.compile("ab*",re.INGNORECASE)

Derlenmiş düzenli ifade nesnesinin metodları:
Derleyerek elde ettiğimiz düzenli ifade nesnesi ile neler yapabiliriz bir bakalım. Bu nesnenin inceleyeceğimiz metodları şunlar:
match
search
findall
finditer
split
sub
subn

match(string,pos,endpos):
match karakter dizisinin düzenli ifade şablonu ile karşılaştırmasına kelimenin başından itibaren başlar. Eğer bir eşleşme bulunmaz ise None bulunursa match nesnesi geri döndürür. pos ve endpos parametreleri seçimliktir. pos kelime dizisinin neresinden başlayacağını endpos ise neresinde biteceğini belirtir. Eğer endpos değeri pos değerinden küçük olursa eşleşme yapılmaz.^ metakarakteri şablonda kullanılırsa pos parametresi değerlendirilmeden kelimenin başından eşleştirilmeye başlanır. p bir derlenmiş edilmiş düzenli ifade nesnesi olarak kabul edilirse;
p.match(karakterdizisi,0,30) ifadesi ile,
p.match(karakterdizisi[:30],0) ifadesi birbirine eşittir.

Eğer verilen karakter dizisinin herhangi bir yerine eşleme yapılmak isteniyorsa search() metodu kullanılmalıdır.

search(string,pos,endpos):
Düzenli ifade şablonun karakter dizisinin içinde aranıp herhangi bir yerine eşlenip eşlenmediğine bakmak için search metodu kullanılır. Eğer eşleme varsa match nesnesi yoksa None döndürülür.
pos ve endpos parametreleleri seçimlik olup kullanım amacı match() metodunda ki ile aynıdır.

Şimdi bir kaç örnek inceleyelim.

>>> import re
>>> p=re.compile("lin")
>>> m=p.match("linux")
>>> print m
<_sre.SRE_Match object at 0x408b7560>

Görüldüğü gibi "lin" kelimesinden derlenmiş düzenli ifade nesnesi elde ettik. bu nesnenin match metodunu kullanarak "linux" ile eşleme yaptık ve eşleme olduğu için match nesnesi elde ettik.

>>> p=re.compile("lin")
>>> m=p.match("suselinux")
>>> print m
None
>>> m=p.match("suselinux",4)
>>> print m
<_sre.SRE_Match object at 0x408bd1a8>

Daha önceki düzenli ifade nesnesini "suselinux" ile eşleştirmeye çalıştığımızda eşleme olmadığını görüyorsunuz. Çünkü match metodu ilk karakterden itibaren eşleme olup olmadığına bakıyor. Ancak ikinci denemede pos değeri 4 olarak verildi ve eşleme var. Çünkü "suse" karakterleri dikkate alınmadı ve değerlendirme 4. karakterden sonrası için yapıldı.

>>> p=re.compile("lin")
>>> m=p.search("suselinux")
>>> print m
<_sre.SRE_Match object at 0x408bd250>

Search metodu "suselinux" kelimesinin ortasındaki "lin" karakter dizisine eşleme yapıyor ve bize match nesnesi döndürüyor.

findall(string,pos,endpos):
findall metodu eşlenen karakter dizilerini bir liste içinde bize verir. Eğer düzenli ifademizdeki birden daha fazla gruba eşleme yapılırsa bunları liste içindeki bir tüpte verir. Eşleme yapılmadığında boş bir liste döndürür. pos ve endpos parametreleri isteğe bağlıdır.

>>> p=re.compile("s")
>>> p.findall("ananas")
[’s’]
>>> p=re.compile("(an)")
>>> p.findall("ananas")
[’an’, ’an’]
>>> p=re.compile("(a(na))")
>>> p.findall("ananas")
[(’ana’, ’na’)]
>>> p=re.compile("(ana)(nas)")
>>> p.findall("ananas")
[(’ana’, ’nas’)]
>>> p.findall("karpuz")
[]

finditer(string,pos,endpos):
finditer bize bir iterator nesnesi verir. Bu iterator nesnesi herbir eşleme için bir bir match nesnesi döndürür.

>>> p=re.compile(".")
>>> iterator=p.finditer("abcdefg")
>>> iterator
<callable-iterator object at 0x40890bac>
>>> for i in iterator:
*print type(i)

*
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
<type ’_sre.SRE_Match’>
>>> iterator=p.finditer("abcdefg")
>>> for i in iterator:
*i.span()

*
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
(5, 6)
(6, 7)

split(string,maxstring=0):
Bu metod karakter dizisini şablona eşlenen karakterlerden bölerek sonucu bize bir liste içinde verir. Eğer şablonda grup kullanılmışsa bu grubların eşlendiği karakter dizileri döndürülen listenin elemanı olur.

>>> p=re.compile("\\W")
>>> p.split("elma,armut,ayva")
[’elma’, ’armut’, ’ayva’]
>>> p=re.compile("(bir)")
>>> p=re.compile("(\\W)")
>>> p.split("elma,armut,ayva")
[’elma’, ’,’, ’armut’, ’,’, ’ayva’]

sub(repl,string,count=0):
Bu metod şablon ile eşleşen her karakter dizisini bulur ve repl parametresi ile verilenle değiştirir. Eğer eşleme yapılmazsa sonuç hiç değiştirilmeden geri döndürürlür. repl parametresi bir karakter dizisi olabildiği gibi bir fonksiyonda olabilir. repl paramteresinde grup refanrasları kullanırsa bu eşleşen karakter dizisi ile değiştirilir. Boş eşleştrmelerde bir önceki eşlemeye bitişik olmadığı zaman değiştirme yapılır.
Bu metodla birlikte başka bir kaçış karakterini daha inceleyelim. \\g<isim>. Bu ifade ile şablonumuzda (?P<isim>) ifadesi kullanılarak eşleşme yaptırdığımız isimlendirilmiş karakter gruplarını yer değiştirme işlemlerinde kullanabiliriz. \\g<sayı> ifadeside \\sayi ifadesinin yaptığı işi yapar. Ancak bazı durumlarda \\sayi ifadesinin yapamadığınıda yapar. Mesela \\30 ifadesini değiştirme işleminde kullandığımızı düşünelim. Burda bizim istediğimiz 30 nolu grup değil 3 nolu grup ve 0. Ama bu 30 nolu grup olarak yorumlanacaktır. Bunu \\g<3>0 şekinde yazıp işimizi görebiliriz.
count parametresi ile yapılan eşleştirmelerden kaçının değişeceğini belirleyebiliriz. Bu parametre pozitif tamsayı değerler alır. Verilen değer kadar değiştirme yaplır. Değer 0 olursa bütün değiştirme işlemleri yapılır.

Örnek 1:

>>> p=re.compile("windows")
>>> print p.sub("linux","işletim sistemim windows")
işletim sistemim linux
>>> print p.sub("linux","işletim sistemim linspire")
işletim sistemim linspire

Örnek 2:

>>> def verial():
*veri=raw_input("İşletim sisteminiz nedir?\\n")
*return veri

>>> p=re.compile("os")
>>> print p.sub(verial(),"işletim sistemim os")
İşletim sisteminiz nedir?
linux
işletim sistemim linux

Örnek 3:

>>> p=re.compile(r"test[(](bir)[)]")
>>> print p.sub(r"örnek(\\1)","test(bir),örnek(iki)")
örnek(bir),örnek(iki)

Örnek 4:

>>> p=re.compile("x*")
>>> print p.sub("-","abxc")
-a-b-c-
>>> print p.sub("-","abc")
-a-b-c-

Örnek 5:

>>> p=re.compile(r"test[(](1)[)]")
>>> print p.sub(r"örnek(\\10)","test(1),örnek(2)")

Traceback (most recent call last):
File "<pyshell#4>", line 1, in -toplevel-
print p.sub(r"örnek(\\10)","test(1),örnek(2)")
File "/usr/lib/python2.4/sre.py", line 260, in filter
return sre_parse.expand_template(template, match)
File "/usr/lib/python2.4/sre_parse.py", line 781, in expand_template
raise error, "invalid group reference"
error: invalid group reference
>>> print p.sub(r"örnek(\\g<1>0)","test(1),örnek(2)")
örnek(10),örnek(2)
>>> p=re.compile("kelime")
>>> p.sub("sözcük","kelime,kelime,kelime,kelime",2)
>>> print p.sub("sözcük","kelime,kelime,kelime,kelime",2)
sözcük,sözcük,kelime,kelime

subn(repl,string,count=0):
sub metodu ile aynı işi yapar fakat sonuc değiştirilmiş karakter dizisi ve değiştirme sayısını içeren bir tüp şeklinde döndürürlür.

>>> p=re.compile("bir")
>>> print p.subn("iki","bir kalem bir defter bir kitap")
(’iki kalem iki defter iki kitap’, 3)

MATCH NESNESİ:
match ve search metodları eşleme yaparsa match nesnesi döndürür demiştik. Şimdi bu match nesnesini bir inceleyelim bakalım neler varmış.

start
end
span
group
groups
groupdict
expand

start(group):
Bu method bize eşlemenin başladığı karakterin kelime içindeki indeksini verir. group parametresi opsiyoneldir. Verilen grup numarasına ait grubun yada verilen isme ait grubun başlangıç indeksini verir.

>>> p=re.compile("lin")
>>> m=p.match("linux")
>>> m.start()
0
>>> m=p.search("suselinux")
>>> m.start()
4

end(group):
Bu metod da eşlemenin bittiği karakterin kelime içindeki indeksini verir. group parametresi opsiyoneldir. Verilen grup numarasına ait grubun yada verilen isme ait grubun bitiş indeksini verir.

>>> p=re.compile("lin")
>>> m=p.search("mandrivalinux")
>>> m.end()
11

span(group):
Bu metod eşlemenin yapıldığı karakterlerin başlama ve bitiş indekslerini bir tüp içinde verir. group parametresi opsiyoneldir. Verilen grup numarasına ait grubun yada verilen isme ait grubun başlangıç ve bitiş indeksini verir.

>>> p=re.compile("lin")
>>> m=p.search("ubuntulinux")
>>> m.span()
(6, 9)
>>> "ubuntulinux"[6:9]
’lin’

group(group1,...):
Bu metod bize eşlenen bir yada daha fazla sayıdaki grubu verir. group parametresi opsiyoneldir. Eğer bir parametre verilirse geriye eşlenen grubu karakter dizisi şeklinde verir daha fazla parametre verildiğinde eşlenen grupları bir tüp içinde verir. group() metodunun varsayılan parametresi 0 dır. Paramete 0 olarak verildiğinde eşleneni karakter dizisi olarak geri döndürür. group() metodu [0..99] arasında tamsayı değerleri kabul eder. negatif değer verildiğinde yada büyük bir sayı verildiğinde IndexError hatası verir.
Eğer şablon içerisinde (?P<isim>) ifadesi kullanılmışsa parametre olarak bu ifadedeki isim verilebilir.

>>>p=re.compile(“lin”)
>>> m=p.search("özgür işletim sistemi linux")
>>> m.group()
’lin’
>>> p=re.compile("(lin)(ux)")
>>> p.match("linux").group(1,2,0,2,1)
(’lin’, ’ux’, ’linux’, ’ux’, ’lin’)
>>> p=re.compile("(?P<id1>lin)(?P<id2>ux)")
>>> p.match("linux").group("id1","id2","id2",0,1,2)
(’lin’, ’ux’, ’ux’, ’linux’, ’lin’, ’ux’)

groups([default]):
Bu method şablon içinde tanımlanan ve eşlenen bütün grupları bir tüp içinde döndürür.

>>> p=re.compile("(?P<id1>lin)(?P<id2>ux)")
>>> p.search("linux").groups()
(’lin’, ’ux’)

groupdict([default]):
İsimlendirilmiş bütün grupları bir sözlük içnde döndürür. Anahtar olarak gruplara verilen isimler kullanılır.

>>> p=re.compile("(?P<id1>lin)(?P<id2>ux)")
>>> p.search("linux").groupdict()
{’id2’: ’ux’, ’id1’: ’lin’}

expand(template):
expand template ile verilen karakter dizisi içindeki numerik grupları(\\1,\\2 gibi) ve isimlendirilmiş grupları(\\g<1>,\\g<isim> gibi) eşlenen karakter dizi ile değiştirir.

>>> p=re.compile("(suse)(?P<os>linux)")
>>> m=p.match("suselinux")
>>> print m.expand(r"kullandığım \\g<os> dağıtımı \\1.\\n\\g<os> kullanmayı seviyorum.")
kullandığım linux dağıtımı suse.
linux kullanmayı seviyorum.

Reklamlar
  1. Henüz yorum yapılmamış.
  1. No trackbacks yet.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

%d blogcu bunu beğendi: