Pythontr

husonet | Tarih: 08.03.2015

Python Düzenli İfadeler

Python Düzenli İfade operasyonları ve Dizi Servisleri

DÜZENLİ İFADE OPERASYONLARI

Bu modül Perl programlama dilleri ile düzenli ifade operasyonlarını eşleşmeyi sağlıyor. Her iki şablon ve dizi serisinde hem Unicode dizisinde hem de 8 bit li dizilerde eşleşme sağlayabilir.


Düzenli ifadelerde özel formları belirtmek içn ters slash ('\') işareti kullanılır. Ya da özel anlamı olmayan özel karakter içeren yerlerde kulanılır. Python’un kullanımında aynı karakterler aynı amaç içinde dizi değişmezleri, mesela eşleştirmede ters slash bu şekilde olabilir ( '\ \ \ \'). Dizi şablonlarında olduğu gibi çünkü düzenli ifadede olmalıdır ('\ \' ). Ve her bir ters slash Python dizisi kütüphanesinde ifade edilmelidir.


Çözüm olarak; Python dizisi notasyonu aralığında düzenli ifade şablonlarında, ters slash her özel ifadede el ile değil, gerçek dizi öneki ile beraber (r) ve (r”\ n”) iki karakterli içerir. (\) ve (n) ile birlikte, “\ n” ise tek karakterli bir satır içerir. Genellikle Python kod kullanımında bu aralık dizi ifadesinde şablonlar içerir.


Bu önemli not, çoğu düzenli ifade operasyonlarında, modül seviye fonksiyonlarında ve RegexObject metodunda yer alır. İlk regex object derlemesinde bu fonksiyon kısayollar içermez, ama kaçırmadan bazı iyi ince ayar parametreleri burada önemlidir.


Düzenli İfade Söz Dizimi

Düzenli ifade yada (RE) eşleşme dizisinde bir ayar belirtir, yeni düzenli ifade formunda birleştirilmiş olabilir. Eğer A ve B ikiside düzenli ifade isenden sonra AB de bir düzenli ifadedir. Genel olarak bakıldığında eğer a bir string ise ve p eşleşmede varsa A ve başka string q , B ile eşleşir. Pq dizisi (string) AB ile eşleşir. Bu tutum olmadıkça A yada B öncelik seviyesi düşük olur. Sınır durumlarında A ve B aralığında yada grup referanslarında numaralanırlar. Böylece karmaşık ifadeler kolay olabilir, burada anlatılanlar gibi basit bir şekilde yapılabilir. Teori ayrıntıları ve düzenli ifadeler uygulanması için Friedl kitabına danışılabilir ve referansında ya da herhangi bir kaynakta hakkında yorum yapılabilir.


Düzenli ifadeler Regular expressions hem özel hem de standart karakterler içerebilir. En çok kullanılan karakterler “A”, “a”, ”0” bunlar en çok kullanılanlarıdır. Arada sıradan karakterler de kullanılabilir, yani last karakteri ‘last’ ile birleşim sağlar.(Bu bölümün geri kalanında düzenli ifadeyi (RE) this special style de yaparız, genellikle tırnak ve string işlemleri olmadan gerçekleştirilemez ‘in single quotes’.)


‘I’ yada ‘(’ gibi bazı karakterler bunlar da özel karakterlerdir. Çevrelerindeki düzenli ifadelerin de nasıl yorumlandığı da etkileyebilir. Düzenli ifade pattern dizeleri null byte içermez, ama byte ‘ı boş kullanarak da belirtebiliriz.
umber notasyonu


Gelelim özel karakterlere. Özel karakterleri aşağıda açıklamaları ile beraber anlatacağım.


“.” (Dot.) Default modda bu eşleşmelerde sarı içinde her hangi bir karakter ile eşleşir. Eğer DOTALL belirtilmişse bu eşleşme her hangi bir karakteri satır içinde arar.


“^” (Caret) Stringler de eşleşmeye başladığında ve MULTILINE modu hemen herbir satır başını ifade eder.


‘$’ String sonundaki eşleşmede yada sadece önceki satırda string sonunda ve MULTILINE satırdan önceki eşleşmede modunda. Örneğin Foo eşleşmesi “foo” ve “foobar” düzenli ifadeler ile birlikte “foo$” sadece “foo” ile eşleşir. Daha enteresan olanı ise bu örnekte ki gibi “foo.$” ı “foo1\ nfoo2\ n” arıyor ise “foo2” ile eşleştiriyor olacaktır normalde, ama “foo1” MULTILINE modunda arama yapıyor ise “$” için bir tek tek arıyor olacak “foo\ n” ,için iki boş eşleşme bulur, satırdan sadece bir öncekini ve bir tane de string sonunda buluruz.


“*” 0 veya daha fazla tekrarını eşleşmesi gibi birçok neden muhtemeldir. Örneğin ab* deseninde eşleşecek bir, b numarasını takip eden her hangi bir karater ya dizisini önemi olmayacaktır.


“+” 1 veya daha fazla tekrarları ile eşleşebilir, Örneğin ab+ deseninde b en az bir tane olma şartıyla sonuç üretir.


“?” 0 veya 1 eşleşmesini tekrarlar. Örneğin "abc?” “b” yada “bc” ile eşleşir.


*?,+?,?? “*”,”+”, ve “?” elemanlarının hepsi açgözlü davranırlar. Mümkün olduğunca text ile eşleşirler. Bazen bu davranış istenmediği gibi olabilir. Eğer RE <.*> ise <H1>title</H1> ile eşleşir. Burada string eşleşme olur ama sadece <H1> ile olur.


{m} Bir önceki karakter ile m kopya eşleşmesi gerektiğini belirtir. Mesela a{3} tam olarak aaa karakteri ile eşleşir.


{m,n} Önekinde bulunan ifadeyi en az m en çok n kez tekrarlar. eşleşme çalışırken mümkün olduğunca çok sayıda tekrarlar. Mesela a{3,5} eşleşecekse 3 den 5 e kadar {a} karakter arar. Örnek verecek olursak a{4,}b ile “aaab” eşleşir, yada 1000 adet “a” karakteri takip eder “ab” tarafından ama “aaab” tarafından etmez. Burada virgül ihmal edilmez, yada modifiye olur daha önce tarif edilen bir şekilde karıştırılmamalıdır.


{m,n}? Eşleşme m den , n‘ye önekinde bulunan ifadeyle eşleşmeye çaışırken, mümkün olduğunca az tekrarlar. Bu açgözlü olmayan versiyonu önceki niteleyicisidir. Mesela 6 karakterli “aaaaaa” dizisi, a{3.5} eşleşir 5 karakterli “aaaaa” dizisi ile, bununla birlikte sadece 3 karakterli a{3,5}? İle eşleşir.


[b]“\” Her iki özel çıkış karakterleri (müsait eşleşme karakterler benzerdir “*”,”?” vb.) yada sinyaller özel bir dizidir, özel dizi aşağıdaki gibidir.[/b]

Eğer ham dizi kullanacak değilseniz model ifade etmeyi, unutmayın. Python da string içinde bir kaçış dizisi olarak ters slash kullanır. Çıkış düzeni Python ayrıştırıcı tarafından tanınan, ters slash ve akabindeki karakter içerir sonuçtaki dizide. Aslında eğer Python sonuç dizisini tanıyabilse idi, ters slash(\ \) iki kere olmalıydı. Bu biraz karmaşık ve anlaması zordur, bu suretle tavsiyemiz, en basit ifadeler, sade dizi kullanmanız yönündedir.


[ ] Karakter kümesi belirtmek için kullanılır


  • Karakterler ayrı ayrı listelenebilir. Mesela [trb] ile “t”,”r”,”b” eşleşebilirler.
  • Karakterlerin sınıflandırılması sergilenebilir, iki karakter tarafından bağışlanabilir ve bir “a” tarafından ayırt ediyor.
  • Mesela [a-z] desenindeki eşleşme, bütün küçük harfli ASCII harfini kapsar, [0-5],[0-9] desenindeki eşleşme bütün bu iki digitlik numaralar 00 dan 59 a kadar birbiri ile eşleşme sağlar. Ve [0-9A-Fa-f] bütün ondalıklı digitlere ile eşleşir. Eğer – yerine ters slash kullanılırsa [a\-z] "a","-","z" ile eşleşir yada eğer ilk karakter ardına yerleşirse yada [a-] desenindeki gibi olursa, "a", “-“ ile eşleşir.
  • Özel karakterler içinde kendi özel anlamını yitirebilirler. Mesela [(+*)]bütün gerçek karakterlerle. “(“, ”+”, ”*”, “)” eşleşir
  • Karakter sınıfları bir çeşit \w , \s (altta tanımlandı) tamamı bir dizi içinde yer alır, bu karakterlere rağmen eşleşmeye bağlıdırlar. LOKALDE ve UNICODE yürürlükte olan moda bağlıdır
  • Menzil aralığında olan karakterler diziyi tamamlayarak eşleşebilirler. Fakat dizinin ilk karakteri “^” ise bütün karakterler dizi ile uyumlu olmazlar. Mesela [^5] deseninde 5 karakteri dışında eşleşme sağlanacaktır.
  • Gerçek bir eşleşme için bu karakteri “]” bir dizi içinde ters slash ile önüne yerleştirin. Mesela ikisi de [()[\]{}] ve []()[{}] olacak bir parantez eşleşme olabilir.

“I” veya komutudur öncelikle öneekine bakar öneki yoksa ardından gelen eke bakararak eşleşme sağlar. Dizi içinde veya grup içinde de kullanılabilir. Karakter olarak kullanılmak isteniyorsa \| şeklinde kullanılmalıdır.


(...) Düzenli ifadelerde parantezler gruplama yapmak için kullanılır ve grubun başıyla sonunu ifade ederler. Karakter olarak kullanılmak isteniyorsa dizilerde [(] [)] dizi kullanımı hariç başına ters slash konularak \( \) kullanılabilir.


(?...) Bu bir uzantı gösterimidir. Uzantılar genellikle yeni bir grup oluşturmak için değildir. (?p<name>…) ise bu kuralın tek istisnasıdır.


(?:…) Düzenli parantezi olmayan bir yakalama versiyonudur. Parantez içindekiler düzenli ifadedirler ama substring tarafından eşleşen bir grup yaptıktan sonra alınırve daha sonra başvuru yapamaz


(?P<name>...) Düzenli parantezlere benzer ama grup tarafından eşleştirilmiş alt dize sembolik grubu adı ile erişebilir. Grup adları olmak zorundadır geçerli Python tanımcıları ve her grup adı bir düzenli ifade içinde sadece bir kez tanımlanmış olabilir. Sembolik grup ayrıca numaralandırılmış gruptur sadece grup adında değil.
Named gruplar üç farklı bağlamda olabilir olabilir. Eğer pattern (?P<quote>['"]).*?(?P=quote) (Çift tırnak yada tek biri ile alıntı bir dize eşleşen)



Gruptaki referansın durumuReferans olma yolları
Paternin kendisi ile aynıdır[/td[td]( ?P=quote )( as shown )
\ 1
Eşleşme nesnesi ne zaman ilerliyorsam.group( 'quote' )
m. end( 'quote' ) (etc.)
Dizide geçmişse to the rep1, re.sub ( )’ın argümanıdır \ g<quote >
\ g<1>
\ 1

(?P=name) Grup ismi olan bir geri başvuru ; daha önce grup adı ismiyle eşleşmesi olursa metin eşlenir.


(?#...) Bir yorum,sadece parantez içindekiler göz ardı edilir.


(?=...) Eğer eşleşme … sıradaki eşleşmede her dizi tüketmez. Bu arama bir lookahead regex assertion yani Regex kütüphanesindeki bir ileri yönlü ifadedidir. Mesela Zafer (?=Yılmaz) deseninde sadece 'Zafer ' ve hemen arkasından gelen 'Yılmaz' eşleşmesi gibi.


(?!...) Eğer eşleşmede … mesela sıradaki ile eşleşemez. Böyle olursa negatif bir ileri yönlü ifade olur. Eee peki ne olacak; hemen bir örnekle açıklıyorum Zafer (?!Yılmaz) deseni ile 'Zafer ' eğer 'Yılmaz' tarafından takip edilmez ise eşleşebilecek.


(?<=...) Eşleşme eğer ki mevcut durumda bir eşleşme öncesinde … için mevcut pozisyonu sonlandırabilir. Bu çağırma işlemi pozitif bir ileri yönlü ifadesidir. (?<=abc)def abcdef’ de bir eşleşme bulacaktır. Geriye bakan yedeklemeden beri 3 karakter ve içerdiği pattern eşleşmeleri kontrol eder. Bu pattern içerimi sadece bazı dizeleri sabit uzunlukta aynı olmalıdır. Manası şudur abc yada a I b içerir, ama a* ve a{3,4} içermez. Grup referansları bile eşleşme uzunlukları aynı uzunlukta olmaz ise desteklemez.


Örnek
>>> import re
>>> m = re.search('(?<=huso)net', 'husonet')
>>> m.group(0)
'net'

Bu örnek tire izleyen bir kelime arar.
>>> m = re.search('(?<=-)\w+', 'spam-mail')
>>> m.group(0)
'mail'

(?<!...) Eşleşme eğer mevcut pozisyonda ve dizesinde ise… eşleşme tarafından öncesinde değildir. Buna geriye bakan pozitif ifade deriz.


(?(id/name)yes-pattern|no-pattern) yes-pattern ile eşleşme çalışır. Eğer grup ile id yada isim varsa ve eğer no-pattern yoksa. no-pattern  isteğe bağlı olabilir yada tlanılabilir.


Mesela (<)?(\w+@\w+(?:\.\w+)+)(?(1)>) ifadesi kötü bir e mail eşleşme patternidir.


'\' Ters slash özel dizileri, ve aşağıda listelenen bir karakteri oluşturur. Eğer sıradan karakter listede değilse o zaman elde edilen ifade, ikinci karakter ile eşleşir. Mesela  \$  ile  '$' karakteri \ number Aynı sayıda grup içeriği eşleşir. Gruplar numaralanmaya 1 den başlarlar. Mesela (.+) \ 1  eşleşir 'the the' yada '55 55'ile ama burası önemli 'thethe' ile eşleşemez. (Grupdan sonraki boşluğa dikkat edin). Bu özel diziler sadece ilk 99 gruba bir eşleşme için kulanılabilir. Eğer ilk digitin nmarası 0 ise yada numarası 3 bayt uzunluğunda ise bir grup eşleşme olarak yorumlanamaz, ama karakter olarak 8 li değeri ile olmayacak.


\A Sadece dize başında eşleşir.


\ b Boş dize eşleşmeleri sadece bir kelimenin başında ya da sonunda boşluk gibi karakterler olursa eşleşir. Bu desen stringi önünde r kullanılması gerektirir örneğin r'\ bfoo\ b' gibi.


\B Boş dize eşleşmeleri ama sadece bir kelimenin başında yada sonunda olmasına gerek yoktur. 'python', 'py3', 'py2' değerleri için r'py\B' deseni eşleşmeyi sağlar.


\d UNICODE etiketi tanılanmadığı zaman her ondalıklı digitte [0-9 ] ile eşdeğerdir. UNICODE İle eşleştirilmiş sınıflandırma ne olursa olsun UNICODE karakter özellikleri veritbanında bir ondalıklı rakam olarak tanımlanır.


\D UNICODE etiketi tanılanmadığı zaman digit karakter olmayan ile eşleşir. [^0-9] ile eşdeğerdir. UNICODE İle bir eşleşme olacak Unıcode karakteri dışındaki özellikleri veritabanında bir basamak olarak işaretlenmiştir.


\s UNICODE etiketi tanılanmadığı zaman; herhangi bir boşluk karakteri ile eşleşir. [ \ t\ n\ r \ f \ v] ile eşdeğerdir.


\w UNICODE ve LOCALE etiketi tanılanmadığı zaman; herhangi bir alfasayısal karakter ve alt çizgi eşleşir. [a-zA-Z0-9_] ile eşdeğerdir.


\W UNICODE ve LOCALE etiketi tanılanmadığı zaman; alfanumerik olmayan her karakterle eşleşir.  [^a-zA-Z0-9_]ile eşdeğerdir.


\Z Sadece dizinin sonunda eşleşir. Eğer LOCALE ve UNICODE ile beraber etiklendiği zaman particular sequence için dahildir.


Python dize değişmezleri tarafından desteklenen standart kaçışların çoğu da düzenli ifade çözümleyici tarafından kabul edilir :


\ a      \ b      \ f      \ n
\ r \ t \ v \ x
\

Not olarak \ b kelime sınırlarını belli etmek için kullanılır ve manası da sadece karakter sınıfları içinde geri tuşu kullanılır.


Modül tanımında birkaç fonksiyon, sabit ve istisnalar vardır. Bazı fonksiyonlar tam özellikli yöntemleri ile derlenmiş düzenli ifadeler için basitleştirilmiş versiyonudur. Önemsiz olmayan uygulamalar derlenmiş formu kullanırlar.


re.compile(pattern, flags=0) ifadenin davranış bayrak değeri belirtilerek değiştiriebilir. Alacağı değerler aşağıdaki değişenlerden herhangi biri olabilir. Bit olarak yada (I ) operatörü ile kombine edilir.


Dizi
prog = re.compile(pattern)
result = prog.match(string)

Yukarıdaki tanımlara eşdeğerdir result = re.match(pattern, string)


Fakat re.compile() ifadesi bir programda birkaç kez kullanılacak ise ayrı tanımlanması tasarruf sağlar ve daha verimli olur.


re.DEBUG Derlenmiş ifade hakkında ekrana hata ayıklama bigisi almamıza yardımcı olur.


re.I
re.IGNORECASE Duyarsız harf eşleştirme ifadeleri [A-Z] gibidir. Mevcut lokalde etkilenme olmaz.


re.L
re.LOCALE Mevcut lokale \ w, \ W, \ b, \ B, \ s  ve \ S bağımlı olmasıdır.


re.M
re.MULTILINE Pattern karakteri '^' belirlendiğinde string’in başında eşleşir ve her satırın başlangıcında ve '$' pattern karakterinde string’in en sonunda eşleşir.


'^' Sadece string’in başında default eşleşmede string’in başında ve '$' string’in sonunda, satırdan hemen önce (eğer varsa) string’in en sonunda ise eşleşir.


re.S
re.DOTALL Bir satır içinde '.' her hangi bir karaktere işaret eder ve eşleşir.


re.U
re.UNICODE \ w, \ W, \ b, \ B, \ d, \ D, \ s  ve  \ S  kullanımı UNICODE karakter özellikleri veritabanına bağlıdır.


re.X
re.VERBOSE Bu flag daha güzel düzenli ifade oluşturmak için olanak sağlar. Pattern içindeki boşluk yok sayılır '#' karakteriyle yorumlar oluşturulabilir ters slash öncesi dikkate alınmaz. Aşağıdaki örnekler konuyla ilgili oluşturulmuştur.


a = re.compile(r"""\d +  # integer bir deger için
\. # nokta operatoru
\d * # kurus hanesi icin""", re.X)
b = re.compile(r"\d+\.\d*")

re.search(pattern, string, flags=0) Normal ifade deseninin bir eşleşme üreten ilk konumu arar ve buna karşılık gelen bir dönüş MatchObject nesnesidir.


re.match(pattern, string, flags=0) Stringin başında sıfır veya daha fazla karakter düzenli ifade deseni uyuyorsa, bir gelen MatchObject örneğini döndürür. Hatta MULTILINE modunda bile satır başından eşleşme yapmaya çalışacağını unutmamak gerekir.


re.split(pattern, string, maxsplit=0, flags=0) Desen tarafından dizi oluşturmaya yarar. Yakalama parantezi deseni kullanılır, sonrasında tüm text grupları desenin ayrıca ortaya çıkan listenin bir parçası olarak geri döner. Aşağıdaki örneği inceleyebilirsiniz.



>>> re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

Eğer ayırıcıda yakalama grupları varsa ve eşleşmeler string başında ise sonuç boş string ile başlayacak ve boş string ile bitecektir.


>>> re.split('(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

Split fonksiyonu dizi oluşturma için asla desen olumsuzsa string üzerinde eşleşme ve bölme işi yapmaz.


>>> re.split('x*', 'foo')
['foo']
>>> re.split("(?m)^$", "foo\ n \ nbar\ n")
['foo\ nbar\ n']

re.findall(pattern, string, flags=0) Stringleri bir liste olarak, string deseni ile tüm çakışmayan eşleşmeleri liste olarak döndürür. Stringler soldan sağa doğru taranır. Bir veya daha fazla eşleşme mevcut ise, bir grup listesi verir.


re.sub(pattern, repl, string, count=0, flags=0) Düzenlenmiş olarak bir string döndürür. Desene uyan ifadelerin düzenlenmesini sağlar.


>>>  re.sub('[-]+', '', 'pro----gram-files')
'programfiles'

>>> re.sub(r'\sve\s', ' & ', 'Huseyin ve Pythontr', flags=re.IGNORECASE)
'Huseyin & Pythontr'

re.subn(pattern, repl, string, count=0, flags=0)   sub() ile aynı operasyonu yapar,  düzenlenmiş stringi ve ilave olarak eşleşen kısımların sayısını döndürür.

>>> text = """
abana
Huseyin ve Pythontr
Ahmet ve C#
"""
>>> re.subn(r'\sve\s', ' & ', text, flags=re.IGNORECASE)
('\ nabana\ nHuseyin & Pythontr\ nAhmet & C#\ n', 2)

re.escape(string) Alphanumerik olmayan karakterler için ters slash ekleyerek string döndürür.


>>> tt="deneme nt"
>>> re.escape(tt)
'deneme\ nt'

re.purge() Düzenli ifadeleri cache den temizler.


[h2]Python Düzenli İfade Örnekleri[/h2]
Ondalık Gösterimler
>>> import re
>>> re.findall("\d+\.\d+", "Fiyat 15.4 TL")
['15.4']

Aşağıdaki gelişmiş örneğimiz daha düzgün çalışır. Hem tam sayı hem de reel sayıları yakalar.


>>> import re
>>> re.findall(r"[-+]?\d*\.\d+|\d+", "Hava derecesi -10.2 aralıklarında 13.2 en yüksek sıcaklık 5")
['-10.2', '13.2', '5']