16.07.2022
49
Like
565
Views
Regex Nedir Nasıl Kullanılır?
Herkese merhaba ben yağız bu gün sizlere regexi anlatacağım ve anlatırken bilmenizi isterim ki çok heyecanlıyım.
Amacım çok fazla teknik terim kullanmadan regexi anlamanız.
Sözüm meclisten dışarı şöyle bir fotoğraf aslında tüm derdimi anlatır zaten bir yazılımcı olarak milyon tane içerik detay bilgi bilmek zorundayız ama artık modern dünyanın en önemli mesleği olan(veri bilimi), kirli ve gereksiz bilgilerin içinde düzgün temiz bilgiyi almak.
Öncelikle bana bu konuda en çok katkısı geçen Gökhan Kandemir'in yazdığı döküman'ı alıntıladım ve bu içerikte bazılarını sizinle de paylaşıcağım .Kendisine Türkçe Yazılım alanındaki sağladığı içerik ve emekleri için ayrı bir şekilde teşekkür etmek isterim.
Ve lütfen google a regex editör yazdığınızda önünüze çıkan editörlerden biri yan sayfada açık olsun.
O zaman regexin tanımıyla başlıyalım. regex "Regular Expressions"(Düzenli İfadeler) anlamına geliyor.
ne demek bu düzenli ifadeler ?
Wiki: Bilgisayarcılıkta düzenli ifadeler veya kurallı ifadeler, ele alınan metindeki kimi katarların kısa yoldan ve esnek bir biçimde belirlenmesini sağlar. Bu katarlar belli karakterler, kelimeler veya karakter örüntüleri olabilir.
Başkası: Regular Expressions (Düzenli İfadeler) kelimesinin kısaltması olan regex, e-posta adresi, tarih, telefon numarası gibi kullanıcı tarafından girilen ve belirli bir düzen içeren girdilerin kontrolünün sağlanması ve herhangi bir kod, metin içerisinde istenilen yazı veya kod parçasının aranıp bulunmasını, yönetilmesini sağlayan kendine ait söz dizimi olan bir yapıdır.
Bana göre: Allahın belası milyon tane satırın içindeki istediğimiz verileri(String) çıkartmak için
en hızlı (ama kolay olmayan) şekilde çıkarmanın yolu.
peki bu regexi neden öğrenmeliyiz ?
aslında sebebi çok basit çünkü string değişken olan her yerde kullana bilceğiniz bir ayıraç.Ve en güzel kısmı dünyanın her yerine gittiğinizde birine Money derseniz sizi nasıl anlıyorsa,şuanda size hangi popüler yazılım dilleri diye sorduğum anda aklınıza gelen tüm dillerde regexi anlıyor.
O yüzden regexi iyi bilen,biri bundan sonra string veriler ile arasında %80 ihtimalle hiç bir problem kalmaz.
Peki regex nasıl çalışır ?
Öyle güzel çalışır ki 😁 ama dilini bilene. Karışık bir yapısı harici anlayabilceğiniz bir şekilde verdiğiniz ifadeleri istediğimiz string datanın içinde ilk önce char olarak teker teker gezip sonra verdiğimiz ifadenin
tamamı ile eşleşen verileri (ben bu eşleşen verilere true eşleşmeyen verilere false olarak anlatıcağım) size geri dönüş sağlar.
Peki kardeşim okadar anlattın hadi artık göster !
İlk olarak size regexi 2 adet slash(/) tuşu ile tanımlaya bilirsiniz yani /blablabla /
ve bu yazı şekli bazı yazılım dillerindede olduğu gibi yazabiliyorsunuz. Ancak bazılarında fonksiyon girdisi olarak yazabilirsiniz yani RegExp(‘regex’,’flag’) gibi üstüne çalıştığınız yazılım dili + regex func yazarsanız
muhtelemen nasıl çalıştığını hızlıca kavrarsınız.
Regexde bazen bazı özellikleri isteriz bu özellikler işte 1’den fazla seçsin, büyük küçük umursamasın, satırları umursamasın, Türkçe karakterleri kapsasın...bunlara özellikleri bizim belirttiğimiz alana biz Flag diyoruz. Bu flagler regexi tanımladıktan sonra arkasına hemen pekiştirdiğimiz harflerden ibaret.
Örnek: /blablabla/gmis o zaman hızlıca Flagleri anlatalım sonra regexin içini anlatmaya başlarız.
Ta Ta Ta Taaaa!
Flags:
g (global): en fazla kullandığımız flag tır.birden fazla true gelen(eşleşen) ifadeler seçer ancak regexin gıcık noktalarından biri,regex her yerde %95 aynı çalışır ama o %5 lik kısım sizin 1 saatinizi belkide gününüzü çalabilir o yüzden tek bir veri bloğu alıcağınız stringlerde bu flagi açmayın.
m (multiline): her bir satiri tek bir string değer olarak almak için kullanılır
i (insensitive): büyük küçük ayrımı yapmaz.
u (unicode) : Güzel Türçemizdeki ve diğer dillerdeki İngilizce hariç yazı dilindeki karakterleri A-Z alfa numeric yazı karakterleri ile bir sayar. Yani eğer Türkçe bir data temizliyorsanız unicode yazın aksi takdirde bu ç neden olmuyor diye düşünür durusunuz.
Burdan sonraki flagleri daha kullanmadım çok spesifik bir durumunuz olmadıkça buradan sonrasına ihtiyacınız yok. O yüzden meta karakterlere geçelim.
Evet sıra regexin içini doldurmaya geldi.peki ne ile dolduracağız ? Meta karakterler ile...
Aman Aman bu o sizin bildiğiniz virtual meta dünya karakterleri değil.😁
buradaki meta anlamınca gerçek olmayan sanal dan daha çok bir işaretleyici koşul anlamında.
Hadi bu karakterler nelermiş bir görelim!!
Meta Characters:
. : nokta karakteri herhangi bir karakteri temsil eder.Diyelimki dana mana bana gibi bir metinimiz var bu metinlerin hepsini almak istiyorsak. ilk karaktere herhangi bir karakter olabilir demek için .ana diyoruz.
/.ana/g
() : gruplama bir veya birden fazla koşulu içeren karakter grubunu tek bir grup içine alır böylece bu karakter grubu sanki tek bir karaktermiş gibi davrana bilir. 4 adet herhangi karakterli değerleri grup içine alalım.
/(....)/g
+ : kendinden bir sonraki karakter kendi ile aynı karakter ise veya izin verdiğimiz karakter grubu ise veya herhangi gruba aldığımız karakter grubu ise false gelene kadar seçmeye devam eder. Ve bu seçtiği tüm karakterleri tek bir grup sayar.4 adet herhangi bir karakterli grubu 4 er 4 er sonuna kadar birleşik halde alalım
/(....)+/
? : sonuna geldiği karakterin veya karakteri grubunun olma zorunluluğunu kaldırır yani dana mana bana bela içerikli string datamızdaki başında lila ifadesi olabilir olursa onuda dahil et demek için
/(lila)?(....)+/
* : + ve ? ‘nin birleşimidir.
Tebrikler artık herhangi basit bir kelime grubunu hızlıca ayıklaya bilirsin.
[] : evet nokta gibi düşüne bilirsiniz ama herhangi bir karakterden daha çok bizim seçtiğimiz karakterler ile eşler(true eder) peki dana hera bela olan karakterlerden 2. karakteri e olan 4haneli karakteri olan stringleri sec demek icin /(.[e]..)+/g ancak bu arkadaşın özellikleri burada bitmiyor. Köşeli parantezimizin içine eğer
a-z A-Z 0-9 gibi ifadeler yazar isek alfa numeric harfleri ve rakamları da kapsar.
Not: içindeki köşeli parantez içindeki her karakter normal karakter sayar sadece a-zA-Z0-9 hariç.
Diyelim ki mana bina bena string değerinin 1.karakter herhangi bir karaktrer 2. karakter sadece a ve e harflerini kapsasın diğer 2 karakterde na karakteri olsun diyelim.
/(.[ea]na)/g
[^] : bu meta karakterimiz ise içine dahil olduğu karakterler hariç karakterleri seç örnek ana bina bena string değerinin 1. karakter herhangi bir karakter olabilir. 2 . karakter ise e ve a harfleri hariç herhangi bir karakter olsun diyelim.
/(.[^ea]na)/g
{}: süslü parantezler bir veya birden fazla veya sonsuz kez bir karater veya karakter grubunu seçmemize yarıyor eğer sadece 3 adet rakam seçmek isterseniz \d{3} yazmanız yeterli ancak diyelim ki en az 3 en fazla 11 adet word karakteri seçmek istiyorsunuz \w{3,11} veya en az 3 adet birbirleri ile yan yana yazılmış yipyipyipyip... kelimelerini sınırsızca seçmek istiyorsunuz.
/(yip){3,}/g
^ : sadece regexin başında yazılabilen veya grubun başına yazılabilen string datanın başlangıçtaki meta characterler şunlar olmak zorundadır diye bilmek için kullandığımız meta karakteri
şöyle: start of RocknRoll olan string datasındaki sadece başındaki kelimeyi alalım ve bu kelimelenin aynısından 3 satır alt alta olsun. /^\w+/g ile sadece en üst satırdaki ilk kelimeyi alabilirsiniz
/^\w+/mg ile tüm satırdaki ilk kelimeyi alabilirsiniz.
$ : dolar meta karakteri ise string verinin sonunda şu karakterler olmak zorunda demek için kullanırız
diyelimki end of RocknRoll kelimesinin sadece en son kelimesini almak istiyoruz.
/\w+$/
| : veya meta karakteri bir veya birden fazla karakter grubu o koşulu karşılıya bilir demek için kullanırız.
Diyelimki I love cats but hate snakes string ifadesindeki cats veya dogsda gelse bu ifadenin tamamını seç
/I love (cats|dogs) but hate snakes/g
\ : backslash meta karakteri bizim isveç çakılarımızdan biridir. Eğer özel meta karakterleri string datanın içinde arıyırıcaksak +*? gibi \? koymanız onu meta karakterden normal bir karaktere çevirecektir. Eğer özel bir meta karakter çağıracaksak sadece yazılar sadece sayılar gibi bu meta karakterin yanına bir karater ekliyerek çağıra bilirsiniz bu meta karakterleri size göstericeğim ancak ilk önce patika.dev linkindeki https://app.patika kısmını alalım
/https:\/\/app\.patika/g
\w : kelime meta karakteri A-Z a-z 0-9 ve _ arasındaki tüm karakterleri seçer. Herhangi bir metindeki tüm kelimeleri seçelim
/\w+/g
\W: kelime meta karakterinin tam tersi kelime olmayan karakterleri seçer.
/\W+/g
\d : sadece rakam olan karakteri seçer.
\D : rakam olmayan tüm karakterleri seçer.
\s : sadece boşluk olan karakterleri seçer.
\S: boşluk olmayan tüm karakterleri seçer.
buraya kadar geldiğinize göre şöyle bir testi çözebilirsiniz diye düşünüyorum. yoksa çözemezmisiniz?
\b : boundarys yazdığımız ifadenin önüne geldiğinde kendinden önceki ifadelerin bir word(\w) grubundan bir karakter olmaması zorunda olduğunu söyleriz. Eğer ifadenin sonuna gelirse de kendinden sonraki karakterin herhangi bir A-Za-z0-9 olmaması gerektiğini söyleriz. diyelim ki word boundaries are odd win to war happenies again string verisindeki sonunda word karakteri olmayan s karakterlerini bulalım.
/s\b/g
\B : non boundarys boundarys in tam anlamıyla tam tersidir. Hergangi bir word karakteri olmak zorundadır.
\K : aradığmıız string değer içindeki bir ifade veya grubu bulduktan başlangıç noktamız string değerin başı yerine o bulduğumuz değerin sonu olur. Diyelim ki 123,456,789 string verimizdeki ilk 3 rakamı bulduktan sonra diğer rakam ve virgülleri seçmek isteyelim.
/[\d]+\K[\d,]+/
\1 \2 :backrefference(gerireferanslar) bir grubun aynı ifadesini çağırmak için kullanılırız. İşratecidir aslında herhangi bilmem kaçıncı numaralı grubun aynısını koşula yazamadığımızda ancak o kosulun aynısını referans ettiğimizde kullanılırız. Çok nadirdir ancak birbirlerini tekrar eden kelime gruplarında çok iyi iş yaparlar bu meta karakterler. Diyelim ki bir html dosyasının içinden Testing <B><I>bold italic</I></B> text.
İçerdeki bold italik yazısının b ve ı elementleri ile çekmeye çalışıyorsunuz.
/<([A-Z][A-Z0-9]*)\b[^>]*>(.*)?<\/\1>/g evet ilk basta bende anlamakta zorlandım.
burdan sonraki backslashli ifadeleri çok nadir kullanılan ifadeler o yüzden bilmenize çok gerek olduğunu zannetmiyorum.
Backslasli meta karakterleride öğrendiğimize göre buraya şöyle bir test bıraksam sizin için pek bir sakıncası olcağını zannetmiyorum.
Geldik parantezli meta karakterlere...
(?=...) : lookahead kendisinden önceki kelimenin seçilmesi için önce bu meta karakterinin koşulunun (true)karşılanması gerekir. Diyelimki foobar foobaz string verisindeki foo yu ama sonunda baz olan foo yu almak istesek.
/foo(?=bar)/
(?!...) : negative lookahead, lookaheadin tam tersi. Diyelim ki foobar foobaz string verisindeki foo yu ama sonunda baz olmayan foo yu almak istesek.
/foo(?!bar)/
(?<=...) : lookbehind bir karakter veya karakter grubunu almak istediğimizde önünde şu karakter veya karakter grubu olmak zorunda demek istediğimiz zaman kullandığımız meta karakter. Diyelimki foobar fuubar string verimizdeki önünde fuu olan bar ı almak istiyoruz.
/(?<=fuu)bar/
(?<!...) : negative lookbehind,lookbehind ın tam tersidir.Diyelimki foobar fuubar string verimizdeki önünde fuu olmayan bar ı almak istiyoruz.
/(?<!fuu)bar/
/match this (?:match that)/g farkı anlamak için /match this (match that)/g
(?<HelloWorld>..) : bu meta karakterimiz grupları isimlendirmek için kullanırız yön parantezleri grubun başına yazılır içine de bu gruba hangi ad ile çağırmak istersek o ad girilir. diyelim ki 9 haneli bir sayı var ve ben bu haneleri ayırmak ve her birini ayrı ayrı grup halinde almak istesem.
/(?<milyonlar>\d{3})[ ]?(?<binler>\d{3})[ ]?(?<yuzler>\d{3})/
Examples:
Burada size çok fazla kullanılan örnekleri vericeğim
Telefon numaralarını seçmek :
1234567890
123-456-7890
123 456 7890
(123) 456-7890
+1 123 456 7890
regex = /((?<area>\+\d{1,2})[ -])?\(?(?<operator>\d{3})\)?[ -]?(?<main>\d{3})[ -]?(?<number>\d{4})/gm
Tarih seçmek:
14/02/2018
14-02-2018
14.02.2018
14.02.18
regex= /(?<day>([0-9]{2}))([\/\-\.])(?<month>([0-9]{2}))([\/\-\.])(?<year>([0-9]{2,4}))/mg
Url secmek:
[https://www.patika.dev~reactogreninogretin]
[https://www.klasikyazilimci.com,php-oldu-abi-artik]
[https://www.youtube.com/kodluyoruz|patika youtube kanalı]
regex= /(?<url>(?<=\[)(.*)(?=[~,\|]))[~|,|\|](?<title>(?<=[~|,|\|])(.*)(?=\]))?/gm
Daha fazla örnek için codewarsın regex adlı testlerini çözebilirsiniz bir gününü buna ayırmanızı tavsiye ederim. bir daha regex de şu nedir veya bu nedir dememek için.
Not: 7 kyu seviyesinden düşük 6,5,4 vb. ilerisindeki regexler için saatleriniz veya günleriniz kesin olarak gidebilir bu yüzden eğer zamanınız değerli ise bulaşmayın derim.
Bu yazıyı okuduğunuz için teşekkür ederim. Umarım size yararı olmuştur.
Kaynaklar:
https://www.codewars.com/kata/search/my-languages?q=regex&beta=false
https://towardsdatascience.com/regular-expressions-clearly-explained-with-examples-822d76b037b4
https://github.com/gkandemi/regex
https://www.regular-expressions.info/
https://regex101.com/
https://www.youtube.com/watch?v=bF_zEzFQZuA
You need to log in to be able to comment!