Düzenli ifadeler metin üzerinde işlemler yapabileceğiniz birçeşit dil diyebiliriz. Regular Expression veya kısaca RegEx olarak da bilinmekte. Regex için stringlerin SQL’i desem yanlış söylemiş olmam. Metinler içerisinde çok kapsamlı arama imkanı sunar. Genelde zaman içinde kolay unutulabilmektedir. Bende vaktiyle üzerinde çokca çalışmış olmama rağmen unutabildiğimden, kalıcı olması açısından ve daha sonradan da hızlıca gözatabilmek için kendimde bir özet çıkarmıştım. Hazırladığım bu dökümanı sizlerle paylaşma zamanı geldi.. Buyrun işte RegEx…
Metin ve kodlama kavramına bir gözatalım
================================================================================
Herşeyin başı ASCII kod tablosuna dayanır. ASCII kod tablosunda normal bizim
bildiğimiz alfabe karakterleri, sayılar, noktalama işaretleri, matematiksel semboller
gibi bir çok “GÖRÜNÜR” olarak ifade edilecek karakterler vardır.
Bunlar ekrana herhangi bir font ile bastırılabilen karakterlerdir.
Ekrana yazdırmadan daha önemlisi bilginin hafızada kapladığı baytlardır yani ASCII
karakterlerdir. Mesela yeni bir satırın başladığını biz hafızadaki bu ASCII
karakter yığınına nasıl kodlayacağız? Windowsda bu ASCII 13 ve 10 numaralı
karakterlerin peş peşe yazılmasıyla kodlanmış Linuxde ise sadece ASCII 10
karakteri ile yetinilmiştir.
0×650x660×0A0×150x670×68
bu ifade karışık gelse de aslında çok basittir 16 lık sistemde bir sayı
0xYY şeklinde ifade edilir. 0×00 0×01 0×10 0xFF şeklinde hep 4 karakter
genişliğinde yazılır. Tek basamaklıların başına 0 eklenirki 4 basamak olsun
şimdi yukarıdaki ifadeyi birazcık netleştirmek için açarsak
0×65 0×66 0×0A 0×15 0×67 0×68
şekline dönüşür 0×0A new line ve 0×15 de Carriage return(enter) kodudur.
İkisi yan yana geldiğinde Windows da yeni satıra geç anlamına gelir
bu durumda bu ifadenin çıktısı
AB
CD
şeklinde olur.
Regular Expressions (regex) ilk geliştirilmeye başlandığında satır bazında
düşünülmekteydi. Nokra karakteri (.) tüm karakterlerle eşleşen bi karakterdir
ama \n yani yeni satır bu eşleşme dışındandır. Çünkü satır bazında yorumlama
yapan bi yazılımın yeni satırı anlaması için \n ye bakması gerekirdi dolayısıyla
\n yani yeni satır bu yorumlayıcılar için anlamlıydı.
Günümüzde regexler çok büyük metinlere blok olarak uygulanabilmekteler.
Bu durumda \n nin devre dışı kalması lazım. Perl bunu için bir takım
yaklaşımlar sunmuştur. Her programlam dili de perl e yakın ama kendi yaklaşımlarını
ortaya koymuşlardır. Bi takım derleyici direktifleri ile noktanın (.) eşleşmesinde \n yi
sonlandırıcı olarak dikkate almamasını sağlayabiliyoruz. Böylece metin Blok
olarak işlem görüyor. Bunu programlama dilinden bağımsız olarak
aşmak için nokta (.) yerine [\s\S] de kullanılabilir :)) herşeyin bi çaresi çıkış
yolu vardır.
METACHARECTERS (11 adet)
==============
[
\
^
$
.
|
?
*
+
(
)
{} süslü parantezleri unutmuşum yav
Köşeli parantezlerin içinde \ , ^ , - evet sadece bu üçü kullanılabiliyor.
geriye kalan yazdığın her karakter kendisini ifade eder özel bir kod veya anlam
değerinin dışındadır. Sadece bir kararkterdir.
————————————-
================================================================================
Character class Match
================================================================================
Tek karakteri Hexedecimal (16 lık) sistemde gösterim
\x00
\x01
\x02
.
.
\xFF
================================================================================
Tek karakteri Unicode sistemde gösterim
\u0000
\u0001
\u0002
.
.
\uFFFF
================================================================================
non printable charecters
Not: Windows’da yeni satır \r\n yani #13#10 dur Unix ve Linuxde yeni satır \n dir? ==> 0 veya 1 tane demektir. (önüne geldiği karakterden 0 veya 1 tane)
ÖRN: ked?i d karakterinden 0 veya 1 tanedemek: 0 ise: kei 1 ise kedi
burda ? (soru işareti) d karakteri üstünde ekti eder.
+ ==> 1 veya 1 den fazla (önüne geldiği karakteri etkiler)
* ==> 0 veya 0 dan fazla (önüne geldiği karakteri etkiler)
? + * da dikkat etmen gereken solunda kalan tek karakter üzerinde işlem yapıyor
mesela: abc?d
abc+d
abc*d
Tüm bu ifadelerde etki c harfinedir.
? için c olmasa da olur
yani abd geçerlidir. ama c olacaksa bile 1 tane olabilir. abcd
geçerli ama abccd geçersiz dir çünkü c den 2 tane var.
+ işareti en az 1 tane c gerektirir. ve fazlasını da kabul eder.
bu ifade için abd geçersizdir çünkü c yok. abcd geçerli olduğu gibi
abccd, abcccd, abcccccccccccccd ifadeleri de geçerli olur
* işareti c olmasada olur ama c olursa da ister 1 tane olsun
ister 1000 tane c olsun hepsi geçerli. bu durumda abd geçerlidir
abcd, abccd, abcccd, abccccccccccccccd ifadeleri de geçerli olur
{} ==> ?, +, * ile kesin sayı aralığında işlem yapmak mümkün olmaz {} bize
{n,m} aralığı imkanı sunar (önüne geldiği karakteri etkiler)
ÖRN: abc{2,4}d
bu ifade de {2,4} c üzerinde etki gösterir ve en az 2 en çok 4 adet
c olursa seçilir
abcd 1 tane c var. şarta uymuyor
abccd 2 tane c var. UYDU
abcccd 3 tane c var. UYDU
abccccd 4 tane c var. UYDU
abcccccd 5 tane c var. şarta uymuyor
{n,m} {n,} {n} şeklinde üç formda kullanabiliriz.
{n,m} bahsettiğimiz gibi n ve n aralığında demek
{n,} en az n adet ama fazla olsa da olur demek
{n} tam olarak n adet demek
AÇ GÖZLÜLÜK VE TEMBELLEŞTİRME
. tek karakter seçer taaki \n görene kadar “Find Next” desen tek kararkter döndürür
A. iki karakter dönürür. ilk karakter A ikincisi \n hariç herşey olabilir.
FindNext desen A ile birlikte \n harici herhangi bir karakterin olduğu
toplam iki karakterlik bir sonuç döndürür.
A.+ bu kuşlastiği gibidir. A ile başlar herhangi bir karakteri kabul edecektir
\n ye kadar herşeyi seçebilir.
söz gelimi: A1, A543534345xcvdfgdfgdffdg, a href=”deneme.htm” vs vs
Burda + nın sağına herhangi bir dizginleyen konmamış FENA HALDE AÇ GÖZLÜ ![]()
A.+> A ile başlayan metnin en sonuncu > karakterine kadar devam eden bir seçim var
Abuk subuk>
Ahu6236>>>>>>>>>>>>>>>>>>>>>>>>>>> bu dahi seçilir. sonuçta sonuncu > e kadar gider
A.+?> A ile başlayan ve ilk > karakterine kadar devam eden bir seçim var
Abuk subuk> kabuldür
Ahu6236>>>>>>>>>>>>>>>>>>>>>>>>>>> ifadesinin Ahu6236> kısmı seçilir.
ÖRNEK:
regex: Get|GetValue|Set|SetValue
string: SetValue GetValue functions are in our tutorial.
bizim regex ifademiz olsun ve SetValue yi arıyor olalım
regexlerin işlenme mantığı ifadedeki karakerler hedef stringde aranır
yani REGEXE stringe UY-GU-LA-NIR.
Çözümleme sırası şöyledir:
bikere regexe yorumlayıcısı bu ifadeyi hemen yorumlar ve | ile bir alternasyon
olduğunu farkındakındadır.
regeximiz şöyle bi açalım efendim
karakterlere nmara sırası verdik
G 1
e 2
t 3
| 4
G 5
e 6
t 7
V 8
a 9
l 10
u 11
e 12
| 13
S 14
e 15
t 16
| 17
S 18
e 19
t 20
V 21
a 22
l 23
u 24
e 25
string: SetValue GetValue functions are in our tutorial.
regexdeki 1. karakter G , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 2. karakter e , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 3. karakter t , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 4. karakter | dır. sol kısım başarısız şimdi | nın sağ kısmına bakıyoruz
regexdeki 5. karakter G , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 6. karakter e , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 7. karakter t , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 8. karakter V , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 9. karakter a , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 10. karakter l , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 11. karakter u , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 12. karakter e , stringdeki 1. karakter S ile eşleşmiyor.
regexdeki 13. karakter | dır. sol kısım başarısız şimdi | nın sağ kısmına bakıyoruz
regexdeki 14. karakter S , stringdeki 1. karakter S ile EŞLEŞTİ.
regexdeki 15. karakter e , stringdeki 2. karakter e ile EŞLEŞTİ.
regexdeki 16. karakter t , stringdeki 3. karakter t ile EŞLEŞTİ.
bu noktada 13. | ile 17. | arasında kalan ifade sağlanmış oldu. ve
SetValue nin Set i seçilmiş oldu ve eşleşme sağlandı.
Peki bu bizim istediğimiz sonuç mudur? Yani biz Stringdeki SetValue yi
arıyor olsak ne olacak? regexde Set yer itibari ile SetValue den önce
geldiği için bu işleşme ancak eşleştirmenin devamı halind ebulunabiliyor.
regexde SetValue ile Set i yer değiştirerek bu sorun çözülebilir. ama daha
iyisi de var. regexi Get(Value)?|Set(Value)? şeklindee yeninden düzenleyeniliriz.
hattaa value bazında da gruplama yapıp (Get|Set)(Value)? şeklindede ifade edebiliriz
GRUPLAMA VE BACKREFERENCE
=================================
BACKREFERENCE sanki bir anlamda değişkeni hafızada tutma gibi bişeydir.
(İFADE) arasındaki ifade otomatik backfererence oluşturur. eğer back ereference
OLUŞTURMAK istenmiyorsa (?:İFADE) şeklinde regexe tanımlanır. ABİ SÜPERİM YAAA ![]()
BİLİYORUM tek rakibim türk hava yoları !!
muhahahaha
peki bu backreference denilen artisti nerede nası kullanırız? aha da örneği!
([a-c])X\1
burada ([a-c]) ifadesi ile ilk backreference kullanılıyo. bu 1 nolu back referencedir.
bu bir nolu backreference keratasına erişmek için \1 kullanılır.
ikinci bi (İFADE) şeklinde backreference olsaydı \2 üçünücüsü \3 şeklinde devam
eder giderdi. çok kolay dimi puhahahahaa
bak yavrucum a-c nin anlamı a veya b veya c den birini gördünmü hemen ensesine yapış! demek ![]()
yapış ama sadece yapışmakla kalma birde aklının bi köşesine yaz demek
ŞİP ŞAAAAAAK!!!
ifadedeki X in bi numarası yok cigerim. Takılma ona. Takılma diyosam takılma
bilader çakarım iki seksen uzarsın
gelelim seksi \1 ifadesine. Tüm hava
tüm karizma bunda! niye dersen zeki! PUHAHAHAA. Zeki çünkü
([a-c]) ifadesi bi karakteri şaaaak diye enseledimi onu burda aynen hatırlar.
bu durumda
aXaXaXaX ifadesinde aXa kısmıyla uyu
bXc uymaz! bXb olsaydı olurdu cigerim MUHAHAHAHAA
dedim sana ben biliyom bu işleri tek rakibim THY uha uha hah ahaaaa
bak şimdi yavrum! ([a-c])X\1([ÖĞ])X\2 İFADESİNDE GÖRDÜĞÜN ÜZRE
2. backreference var. eğer sem dersenki ikinci bakreference hafızada yer kaplamasın
o zaman (?:İFADE) tekniğini kullanırsın. bu durumd ayeni ifade ([a-c])X\1(?:[ÖĞ])X
şeklinde yazman lazım. I AM THE PREFESSIONAL YOU KNOW! :))
HAAA Bİ DURUM DAHA VAR. SENCE () içinde \1 gibi bi başvuru olur mu? olmaz tabi
bu saçmalık!
yani backreference tanımı () olan ifadesinin içinde \1 \2 \3 ..
şeklinde backrefeence yer aaaa laaaa maaaazzz.’! KAPİİİŞ? OKEY YAVRUM KAPİŞ!
([a])\1([b])\2([c])\3([d])\4([e])\5 ifadesi
aabbccddee stringiyle eşleşir. örnek saçma belki ama olsun mevzu anlaşır en azından
(orhan) aynı zamanda bi backreference dir ve \1 ile ona ulaşışabilir. peki
çok fazla backreference olsa bunu numaralarla nası anımsıycaz? e zor olur tabi.
onun için backreferencelere isim vermez olayı vardır:
(?P![]()
ÖRN: (?P
(?P=ADSOYAD) ile de ulaşabiliriiizzz. yuppiiiii
/i makes the regex match case insensitive.
/s enables “single-line mode”. In this mode, the dot matches newlines.
/m enables “multi-line mode”. In this mode, the caret and dollar match before and after newlines in the subject string.
(?i)te(?-i)st ==> Test test Test hepsi olur çünkü te boyut bağımsızdır
LOOKAHEAD, LOOKBEHIND MEVZULARI VARDIR BİRDE.
(?!u) u olmasın demek bu
(?=u) u olsun demek. ama dikkat et u işaretlenmez yada döndürülmez! sadece varlığı test edilir ileriye doğru
q(?!u) q dan sonra u gelmesin demektir ![]()
q(?=u) q dan sonra u gelsin demektir.
(?=(regex)) lookaraound olayında içeride parantez içinde regexe kullanılabilir
(?!(regex)) lookaraound olayında içeride parantez içinde regexe kullanılabilir
GERİYE DOĞRU LOOKBEHIND da aynı mantıktır ama geriye doğru işler
(? (?<=a)b b den önce a olsun
Orhan DOĞAN
Bu gönderiye ait yorumlar için RSS beslemesi · TrackBack URI
Yorum yazın
Yorum göndermek için giriş yapmış olmanız gerekir.