x
Üye
- Katılım
- 30 Ara 2022
- Mesajlar
- 341
- Tepkime puanı
- 31
- Puanları
- 28
İtibar:
Regular expression (regex) Türkçesiyle düzenli ifadeler metinlerde bir biçimsel dil kullanarak tarif edilen kısımları seçip ayırmamıza yarayan bir programdır.
Neredeyse bütün programlama dillerinde kullanılan regex ile metinlerde ayrıştırmak istediğiniz her şeye ulaşabilirsiniz.
Örneğin günümüzde en çok içerik çalma botlarında kullanılır. Fakat yazı düzeni sağlamak ya da metinlerde aranan ifadelere ulaşıp onları manipüle etmek için de kullanabilirsiniz.
Bu yazıda öncelikle regex desenlerini denemek için bir kaç kullanışlı site paylaşacağım, sonrasında temel ihtiyaçları karşılayacak ve en çok kullanılan regex desenlerinden ve bunları PHP ile nasıl kullanacağımızdan bahsetmeye çalışacağım.
Giriş
Yazı boyunca göstereceğim desenleri deneyebilmek için anlık işlemler yapabilen ve her regex çalışmamızda tarayıcımızın bir tabında açık olması gereken bu siteleri mutlaka yer imlerinize ekleyin.
Regex101 (Favorim)
Rubular
Gethifi Regexp Tool
RegExr
Hoşumuza giden bir tanesini açın ve verilen örnekleri canlı bir şekilde deneyerek daha iyi kavrayın.
Bir kelime aramak
Regex ile yapılabileğimiz en basit işlem kelime aramaktır, bunun için direkt aramak istediğimiz kelimeyi yazmak yeterli. Örnek olarak düzenli ifademize “elma” yazıyoruz. Ve elde edeceğimiz sonuçta elma kelimelerinin seçildiğini görebilirsiniz.
Örnek düzenli ifade:
elma
Metin ve sonuç:
Bu deneme amaçlı yazılmış ve içerisinde elma geçen öylesine bir metin.
Yukarıda sarı renkle işaret edilen kelime, yazdığımız ifadenin yakaladığı kelimenin göstergesidir. Bundan sonraki örneklerde de elde ettiğimiz sonuçları böyle göstereceğim.
Özel karakterler
Düzenli ifadelerde bolca anlam ve ifade içeren özel karakterler vardır. Asıl yapmak istediklerimizi bunlarla ifade edip istenilen sonuca ulaşırız. Öncelikle bu karakterlerin ne olduklarına bakalım, sonrasında da nasıl kullanıldıklarını örnekler ile deneyelim.
Düzenli ifadelerde kullanılan özel karakterler:
Karakter Açıklaması
\d Herhangi bir rakamı ifade eder
. Satır başı hariç herhangi bir karakteri ifade eder
\w Herhangi bir harfi, rakamı veya alt tireyi ifade eder
\s Herhangi bir görünmez karakteri ve boşluğu ifade eder. (Boşluk, tab, satır başı gibi)
^ Başlangıcı ifade eder
$ Sonu ifade eder
* Kendinden önce yazılmış karakterin;
sıfır veya daha fazla tekrar etmesini ifade eder
+ Kendinden önce yazılmış karakterin;
bir veya daha fazla tekrar etmesini ifade eder
? Kendinden önce yazılmış karakterin;
olsa da olur olmasa da olurunu ifade eder
{123} Kendinden önce yazılmış karakterin;
parantez içerisine yazılan sayı kadar tekrar etmesini ifade eder
{1, 2} Kendinden önce yazılmış karakterin;
parantez içerisinde yazılan iki sayı arasında tekrar etmesini ifade eder
( … ) Parantez içerisine yazılan ifadeleri gruplamaya yarar
( … | … ) Parantez içerisine yazılan “|” dik tire işareti ya da anlamına gelir, içerisine yazılan ve dik tire ile ayrılan ifadelerden herhangi birisinin eşleşmesini ifade eder
[ ... ] Köşeli parantez içerisine yazılan karakterlerden bir tanesini ifade eder
\ Kaçış karakteri. Yukarıda yazdığımız karakterleri normal olarak yazmak istediğimizde başına kaçış işaretini koyarız. Örneğin noktayı ifade etmek için \.
\D Rakam olmayan herhangi bir karakteri ifade eder
\S Görünmez ve boşluk olmayan karakteri ifade eder
\W Harf, rakam veya alt tire olmayan karakteri ifade eder
\b Kelimenin başını veya sonunu ifade eder
[^ ... ] Üç nokta yerine yazılan karakterler haricindeki karakterleri ifade eder
[a-z] A dan z’ye olan harflerden birisini ifade eder
Regex ayarları
Regex desenleri iki “/” (bölü) işaretinin arasına yazılır. Sondaki bölü işaretinden sonra isteğe bağlı olarak regex ayar karakterleri girilir.
Ayar karaktleri:
Karakter Açıklaması
i Büyük küçük harfe duyarsız olur
g İlk eşleşmede durmaz, kapsamlı tarama yapar
s Satır başı hariç her şeyi ifade eden nokta karakterinin satır başını da ifade etmesini sağlar
m ^ ve $ karakterlerinin her satırın başını ve sonunu ifade etmesini sağlar
Örnek kullanımı:
/elma/i
Bu örnekte büyük ELMA, küçük elma ya da ElMa şeklinde yazılanları da büyük küçük harfe aldırmadan yakalar.
Yukarıdaki örnek selma, elmas gibi kelimelerin içerisindeki “elma”ları da bulacaktır. Eğer sadece elma kelimesini aramak istiyorsak kelime başı ve sonunu ifade eden \b kullanacağız.
/\belma\b/gi
Şimdi sadece elma kelimesini bulacağız, selma, elmas gibi diğer elma içeren kelimeleri yakalamayacaktır.
Sayıları yakalamak
Gelelim şimdi yukarıdaki tabloda listelediğimiz karakterlerin örnek kullanımına. Girilen içerikte sadece sayıları bulmak için “\d” ve “+” karakterlerini kullanacağız.
/\d+/g
Bu örnek sadece 1234, 321 789 sayılarla eşleşir. “g” ayarı ile de bir kere değil kapsamlı aramasını ifade ettik
Bir veya daha fazla tekrarı ifade eden “+” karakterinin başına herhangi bir rakamı ifade eden “\d” yazdık. Daha işe yarar bir örnek için girilen içerikteki tarih formatında yazılmış ifadeyi yakalayalım.
/(\d{2}\.\d{2}\.\d{4})/g
İfadenin karışık görünmesi sizi korkutmasın, ilgili yerlerden inceleyerek ayıkladığınızda ne olduğunu daha rahat özetleyebilirsiniz. \d{2} 2 rakamı, sonrasında \. kaçış karakteri ile noktayı, son kısımda ise 4 rakamı ifade ettik. Böylece 10.08.2013 gibi bir içerikle eşleşecektir.
Kelimeleri yakalamak
Yukarıdaki örnekle benzer bir ifade ile yapabiliriz.
/(\w+)/g
\w ifadesi herhangi bir harfi ifade ettiğini söylemiştik fakat Türkçe karakterlerin bu ifade için istisna olduğunu bilmeniz gerekiyor. Eğer Türkçe bir içerikle çalışıyorsak yapmamız gereken ifade şöyle olmalı;
/([a-zA-ZÇŞĞÜÖİçşğüöı]+)/g
Bu ifade ile Türkçe kelimeleri de yakalayabiliriz
Küçük ve büyük a’dan z’ye harlerin yanına Türkçe’de olan küçük ve büyük harfleri ekledik. Bir diğer örnek olarak da içerikten sadece istenilen bir kelimeyi almayı deneyelim.
/benim adım (\w+)/gi
Merhabalar benim adım Musa!
Başlangıç ve sona göre yakalama
^ ve $ karakterleriyle başının ya da sonunun nasıl olacağını ifade edebiliriz. Örnek olarak sadece selam ile başlayan içeriği ayıklamayı deneyelim.
/^selam/
Bu örnek metin selam ile başlamadığı için hiç bir şeyle eşleşmeyecektir
selam! bu örnek daha samimi olduğu için eşleşecektir
Selam ile başlayan ve hoşçakal ile biten metnin arasında geçenleri yakalayacak bir örnek daha;
/^selam(.+)hoşçakal$/
selam buralar yakalanacak hoşçakal
Düzenli ifadeleri PHP ile kullanmak
Gelelim bu faydalı işlemleri PHP üzerinde kullanmaya. Bunun için bir kaç faydalı fonksiyon ile tanışacağız.
İfadenin eşleşip eşleşmediğini kontrol etmek
preg_match fonksiyonu ile yazdığımız ifadenin verdiğimiz içerikle eşleşmediğini kontrol edebiliyoruz. Örnekte girdinin geçerli bir saat formatı olup olmadığını kontrol edeceğiz.
Eğer ifade metin içerisinde eşleşirse true aksi halde false döner.
Yazdığımız ifadenin açıklamasını da merak ediyorsanız;
Öncelikle ^ ile metnin başını ifade ettik, yani tam olarak bizim istediğimiz gibi başlamalı. Sonunda da $ kullandık, bu sayede tam olarak bizim istediğimiz başlangıca ve sona sahip olan bir içeriği aradığımızı ifade ettik.
Sonrasında ([01][0-9]|[2][0-3]) 2 ifadeyi gruplandırdık. Çünkü saat ya 01 den 19′a kadar ya da 20 dan 23′e kadar olabilir. Eğer [0-9]{2} şeklinde 0 ile 9 arasında 2 sayı ile eşleş deseydik, 99 gibi 23′den büyük sayılara da eşleşirdi.
Yakalanan içerikleri almak
Düzenli ifadelerde yakalamak ve ayırmak istediğimiz içeriklerin ifadelerini parantez içerisinde yazarız. Parantez içerisine yazılan ifadelere eşleşen içeriklere preg_match_all fonksiyonu sayesinde ulaşacağız. Bu fonksiyon tüm içeriği taramasını sağlayan “g” ayarını içerir, yani preg_match_all kullanırken “g” (global) ayarını yazmanıza gerek yok.
Teorik bilgi ve örneklerin haricinde biraz gerçek hayattaki kullanımlarına bakarak daha iyi kavrayabileceğimizi düşünüyorum. Bir sitenin kayak kodundan title etiketi arasında yer alan site başlığını yakalamak için şöyle bir ifade yazabiliriz.
Ekran çıktısı şöyle olacaktır;
$results değişkenindeki dizinin ilk elemanı; girilen ifade ile eşleşen içeriklerin dizisini verir. Sonraki elemanları ise parantezler ile grupladığımız ifadelere eşleşen içeriklerin dizisini verir. Yani bizim asıl ihtiyacımız olan title etiketleri arasında parantez içerisine aldığımız karakterleri almak için 2. elemana bakacağız.
İkinci elemanda kendi içerisinde bir dizi, yani eğer birden fazla eşleşme olursa onları da sırayla verecektir.
Düzenli ifadeleri kullanarak içeriği değiştirme
Yine kullanışlı bir örnek ile açıklayalım. Girilen metin içerisine düz bir şekilde yazılan URL’leri HTML formatında link yapalım. Bunun için öncelikle bir URL’yi ifade edecek olan desen lazım. Ben internette hazır örneklerden birisini seçtim, dilerseniz siz de diğerlerine şuradaki adresten bakabilirsiniz. preg_replace fonksiyonu ile eşleşen ifadelerde yine parantez içinde grupladığımız ifadeleri istediğimiz şekilde değiştirebiliriz.
Neredeyse bütün programlama dillerinde kullanılan regex ile metinlerde ayrıştırmak istediğiniz her şeye ulaşabilirsiniz.
Örneğin günümüzde en çok içerik çalma botlarında kullanılır. Fakat yazı düzeni sağlamak ya da metinlerde aranan ifadelere ulaşıp onları manipüle etmek için de kullanabilirsiniz.
Bu yazıda öncelikle regex desenlerini denemek için bir kaç kullanışlı site paylaşacağım, sonrasında temel ihtiyaçları karşılayacak ve en çok kullanılan regex desenlerinden ve bunları PHP ile nasıl kullanacağımızdan bahsetmeye çalışacağım.
Giriş
Yazı boyunca göstereceğim desenleri deneyebilmek için anlık işlemler yapabilen ve her regex çalışmamızda tarayıcımızın bir tabında açık olması gereken bu siteleri mutlaka yer imlerinize ekleyin.
Regex101 (Favorim)
Rubular
Gethifi Regexp Tool
RegExr
Hoşumuza giden bir tanesini açın ve verilen örnekleri canlı bir şekilde deneyerek daha iyi kavrayın.
Bir kelime aramak
Regex ile yapılabileğimiz en basit işlem kelime aramaktır, bunun için direkt aramak istediğimiz kelimeyi yazmak yeterli. Örnek olarak düzenli ifademize “elma” yazıyoruz. Ve elde edeceğimiz sonuçta elma kelimelerinin seçildiğini görebilirsiniz.
Örnek düzenli ifade:
elma
Metin ve sonuç:
Bu deneme amaçlı yazılmış ve içerisinde elma geçen öylesine bir metin.
Yukarıda sarı renkle işaret edilen kelime, yazdığımız ifadenin yakaladığı kelimenin göstergesidir. Bundan sonraki örneklerde de elde ettiğimiz sonuçları böyle göstereceğim.
Özel karakterler
Düzenli ifadelerde bolca anlam ve ifade içeren özel karakterler vardır. Asıl yapmak istediklerimizi bunlarla ifade edip istenilen sonuca ulaşırız. Öncelikle bu karakterlerin ne olduklarına bakalım, sonrasında da nasıl kullanıldıklarını örnekler ile deneyelim.
Düzenli ifadelerde kullanılan özel karakterler:
Karakter Açıklaması
\d Herhangi bir rakamı ifade eder
. Satır başı hariç herhangi bir karakteri ifade eder
\w Herhangi bir harfi, rakamı veya alt tireyi ifade eder
\s Herhangi bir görünmez karakteri ve boşluğu ifade eder. (Boşluk, tab, satır başı gibi)
^ Başlangıcı ifade eder
$ Sonu ifade eder
* Kendinden önce yazılmış karakterin;
sıfır veya daha fazla tekrar etmesini ifade eder
+ Kendinden önce yazılmış karakterin;
bir veya daha fazla tekrar etmesini ifade eder
? Kendinden önce yazılmış karakterin;
olsa da olur olmasa da olurunu ifade eder
{123} Kendinden önce yazılmış karakterin;
parantez içerisine yazılan sayı kadar tekrar etmesini ifade eder
{1, 2} Kendinden önce yazılmış karakterin;
parantez içerisinde yazılan iki sayı arasında tekrar etmesini ifade eder
( … ) Parantez içerisine yazılan ifadeleri gruplamaya yarar
( … | … ) Parantez içerisine yazılan “|” dik tire işareti ya da anlamına gelir, içerisine yazılan ve dik tire ile ayrılan ifadelerden herhangi birisinin eşleşmesini ifade eder
[ ... ] Köşeli parantez içerisine yazılan karakterlerden bir tanesini ifade eder
\ Kaçış karakteri. Yukarıda yazdığımız karakterleri normal olarak yazmak istediğimizde başına kaçış işaretini koyarız. Örneğin noktayı ifade etmek için \.
\D Rakam olmayan herhangi bir karakteri ifade eder
\S Görünmez ve boşluk olmayan karakteri ifade eder
\W Harf, rakam veya alt tire olmayan karakteri ifade eder
\b Kelimenin başını veya sonunu ifade eder
[^ ... ] Üç nokta yerine yazılan karakterler haricindeki karakterleri ifade eder
[a-z] A dan z’ye olan harflerden birisini ifade eder
Regex ayarları
Regex desenleri iki “/” (bölü) işaretinin arasına yazılır. Sondaki bölü işaretinden sonra isteğe bağlı olarak regex ayar karakterleri girilir.
Ayar karaktleri:
Karakter Açıklaması
i Büyük küçük harfe duyarsız olur
g İlk eşleşmede durmaz, kapsamlı tarama yapar
s Satır başı hariç her şeyi ifade eden nokta karakterinin satır başını da ifade etmesini sağlar
m ^ ve $ karakterlerinin her satırın başını ve sonunu ifade etmesini sağlar
Örnek kullanımı:
/elma/i
Bu örnekte büyük ELMA, küçük elma ya da ElMa şeklinde yazılanları da büyük küçük harfe aldırmadan yakalar.
Yukarıdaki örnek selma, elmas gibi kelimelerin içerisindeki “elma”ları da bulacaktır. Eğer sadece elma kelimesini aramak istiyorsak kelime başı ve sonunu ifade eden \b kullanacağız.
/\belma\b/gi
Şimdi sadece elma kelimesini bulacağız, selma, elmas gibi diğer elma içeren kelimeleri yakalamayacaktır.
Sayıları yakalamak
Gelelim şimdi yukarıdaki tabloda listelediğimiz karakterlerin örnek kullanımına. Girilen içerikte sadece sayıları bulmak için “\d” ve “+” karakterlerini kullanacağız.
/\d+/g
Bu örnek sadece 1234, 321 789 sayılarla eşleşir. “g” ayarı ile de bir kere değil kapsamlı aramasını ifade ettik
Bir veya daha fazla tekrarı ifade eden “+” karakterinin başına herhangi bir rakamı ifade eden “\d” yazdık. Daha işe yarar bir örnek için girilen içerikteki tarih formatında yazılmış ifadeyi yakalayalım.
/(\d{2}\.\d{2}\.\d{4})/g
İfadenin karışık görünmesi sizi korkutmasın, ilgili yerlerden inceleyerek ayıkladığınızda ne olduğunu daha rahat özetleyebilirsiniz. \d{2} 2 rakamı, sonrasında \. kaçış karakteri ile noktayı, son kısımda ise 4 rakamı ifade ettik. Böylece 10.08.2013 gibi bir içerikle eşleşecektir.
Kelimeleri yakalamak
Yukarıdaki örnekle benzer bir ifade ile yapabiliriz.
/(\w+)/g
\w ifadesi herhangi bir harfi ifade ettiğini söylemiştik fakat Türkçe karakterlerin bu ifade için istisna olduğunu bilmeniz gerekiyor. Eğer Türkçe bir içerikle çalışıyorsak yapmamız gereken ifade şöyle olmalı;
/([a-zA-ZÇŞĞÜÖİçşğüöı]+)/g
Bu ifade ile Türkçe kelimeleri de yakalayabiliriz
Küçük ve büyük a’dan z’ye harlerin yanına Türkçe’de olan küçük ve büyük harfleri ekledik. Bir diğer örnek olarak da içerikten sadece istenilen bir kelimeyi almayı deneyelim.
/benim adım (\w+)/gi
Merhabalar benim adım Musa!
Başlangıç ve sona göre yakalama
^ ve $ karakterleriyle başının ya da sonunun nasıl olacağını ifade edebiliriz. Örnek olarak sadece selam ile başlayan içeriği ayıklamayı deneyelim.
/^selam/
Bu örnek metin selam ile başlamadığı için hiç bir şeyle eşleşmeyecektir
selam! bu örnek daha samimi olduğu için eşleşecektir
Selam ile başlayan ve hoşçakal ile biten metnin arasında geçenleri yakalayacak bir örnek daha;
/^selam(.+)hoşçakal$/
selam buralar yakalanacak hoşçakal
Düzenli ifadeleri PHP ile kullanmak
Gelelim bu faydalı işlemleri PHP üzerinde kullanmaya. Bunun için bir kaç faydalı fonksiyon ile tanışacağız.
İfadenin eşleşip eşleşmediğini kontrol etmek
preg_match fonksiyonu ile yazdığımız ifadenin verdiğimiz içerikle eşleşmediğini kontrol edebiliyoruz. Örnekte girdinin geçerli bir saat formatı olup olmadığını kontrol edeceğiz.
PHP:
$pattern= '/^([01][0-9]|[2][0-3]):[0-5][0-9]:[0-5][0-9]$/';
$content = '23:15:59';
if(preg_match($pattern, $content))
{
echo 'Doğru bir saat girilmiş';
}
else
{
echo 'Yanlış bir saat formatı girilmiş';
}
Eğer ifade metin içerisinde eşleşirse true aksi halde false döner.
Yazdığımız ifadenin açıklamasını da merak ediyorsanız;
Öncelikle ^ ile metnin başını ifade ettik, yani tam olarak bizim istediğimiz gibi başlamalı. Sonunda da $ kullandık, bu sayede tam olarak bizim istediğimiz başlangıca ve sona sahip olan bir içeriği aradığımızı ifade ettik.
Sonrasında ([01][0-9]|[2][0-3]) 2 ifadeyi gruplandırdık. Çünkü saat ya 01 den 19′a kadar ya da 20 dan 23′e kadar olabilir. Eğer [0-9]{2} şeklinde 0 ile 9 arasında 2 sayı ile eşleş deseydik, 99 gibi 23′den büyük sayılara da eşleşirdi.
Yakalanan içerikleri almak
Düzenli ifadelerde yakalamak ve ayırmak istediğimiz içeriklerin ifadelerini parantez içerisinde yazarız. Parantez içerisine yazılan ifadelere eşleşen içeriklere preg_match_all fonksiyonu sayesinde ulaşacağız. Bu fonksiyon tüm içeriği taramasını sağlayan “g” ayarını içerir, yani preg_match_all kullanırken “g” (global) ayarını yazmanıza gerek yok.
Teorik bilgi ve örneklerin haricinde biraz gerçek hayattaki kullanımlarına bakarak daha iyi kavrayabileceğimizi düşünüyorum. Bir sitenin kayak kodundan title etiketi arasında yer alan site başlığını yakalamak için şöyle bir ifade yazabiliriz.
PHP:
$pattern = '/<title>(.+)<\/title>/i';
$content = file_get_contents('http://www.phpr.org');
preg_match_all($pattern, $content, $results);
print_r($results)
Ekran çıktısı şöyle olacaktır;
PHP:
Array
(
[0] => Array
(
[0] => <title>php serüvenleri - PHP dersleri, PHP örnekleri, PHP kodları</title>
)
[1] => Array
(
[0] => php serüvenleri - PHP dersleri, PHP örnekleri, PHP kodları
)
)
$results değişkenindeki dizinin ilk elemanı; girilen ifade ile eşleşen içeriklerin dizisini verir. Sonraki elemanları ise parantezler ile grupladığımız ifadelere eşleşen içeriklerin dizisini verir. Yani bizim asıl ihtiyacımız olan title etiketleri arasında parantez içerisine aldığımız karakterleri almak için 2. elemana bakacağız.
İkinci elemanda kendi içerisinde bir dizi, yani eğer birden fazla eşleşme olursa onları da sırayla verecektir.
Düzenli ifadeleri kullanarak içeriği değiştirme
Yine kullanışlı bir örnek ile açıklayalım. Girilen metin içerisine düz bir şekilde yazılan URL’leri HTML formatında link yapalım. Bunun için öncelikle bir URL’yi ifade edecek olan desen lazım. Ben internette hazır örneklerden birisini seçtim, dilerseniz siz de diğerlerine şuradaki adresten bakabilirsiniz. preg_replace fonksiyonu ile eşleşen ifadelerde yine parantez içinde grupladığımız ifadeleri istediğimiz şekilde değiştirebiliriz.
PHP:
// URL'leri yakalayan desen
$pattern = '(https?:\/\/(([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}\/?[^\b\s]+))';
$content = 'Diğer PHP serüvenlerine http://www.phpr.org adresinden bakabilirsiniz';
$replace = '<a href="$0">$1</a>';
echo preg_replace($pattern, $replace, $content);