Temel Regex Kavramları ve PHP'de Regex

Regular Expression (Düzenli İfade) Nedir?

Regular Expression (regex, regexp vb.) veya Türkçe tabiriyle “Düzenli İfadeler”... Ben yazımın ilerleyen bölümünde regex kısaltmasını kullanacağım.

Regex, belirlediğimiz kurallar doğrultusunda metinlerde arama, değiştirme, parçalama vb. işlemleri yapmamızı sağlayan bir yapıdır.

Regex hakkında daha akademik ve geniş bir tanım isteyenler https://tr.wikipedia.org/wiki/D%C3%BCzenli_ifade adresine göz atabilirler.

Regex, birçok dil tarafından desteklenir. Javascript, php, asp, .net dilleri, java, phyton vb. birçok dili bu kategoriye alabiliriz. Ben yazının kalan kısmında php ile bazı temel anlatımlardan söz etmeye çalışacağım.

PHP'de Regex Kullanımı

- Fonksiyonlar:

PHP'de regex'i etkin bir şekilde kullanabilmemiz için eklenmiş birkaç tane fonksiyon mevcut. Bunlar;

preg_match, preg_match_all, preg_replace, preg_replace_callback, preg_split vb. fonksiyonlar PCRE (Perl Compatible Regular Expressions) standartlarını kullanan, php'nin yerleşik fonksiyonlarından bazılarıdır. Bu fonksiyonların tam listesine http://www.php.net/manual/en/ref.pcre.php adresinden ulaşabilirsiniz.

Regex Desenleri Yazılırken Kullanılan Özel Semboller ve Anlamları

- Özel Semboller

^          : Eşleşme başlangıcı

$          : Eşleşme bitişi

\           : Escape. Desende kullanılan özel sembolleri desenin içerisine dahil edebilmek için escape karakteriyle beraber yazmak gerekir. Örneğin ^ karakterini aramak için \^ şeklinde yazmalısınız.

[...]      : [ ] arasına yazılan karakterleri bir sınıf haline getirmeye yarar. Örneğin abc harflerini ayrı ayrı aramak için [abc] şeklinde bir karaker sınıfı oluşturmalısınız.

.           : Herhangi bir karakter anlamına gelir.

|           : Veya

- Karakter Sınıfları ( [...] )

Karakter sınıflarının içerisinde, regex için ayrılmış özel karakterlerin herhangi bir işlevi yoktur. Yalnızca ^ - ] ve \ karakterlerinin özel anlamları vardır.

İçeriğin sırası önemsizdir. Girdiğiniz her karakter tekil olarak aranacaktır. Hepsi tek bir karaktere karşılık gelir.

Örneğin abc harflerini ayrı ayrı aramak için [abc] [bca] [acb] şeklinde karakter sınıfları oluşturabilirsiniz. Hepsi aynı işlevi görecektir.

^ karakteri, karakter sınıflarının başına konulduğunda mantıksal değil anlamı taşır ve karakter sınıfının özelliğini değiştirir.

Örneğin abc olmayanları aramak için [^abc] şeklinde bir karakter sınıfı tanımlayabilirsiniz.

- karakteri karakter sınıflarının içerisinde aralık belirtmek için kullanılır. Örneğin a-z arası alfabe karakterlerini (içerisinde Türkçe karakterler yoktur) içerecek bir karakter sınıfı hazırlamak için [a-z] şeklinde tanımlama yapabilirsiniz. Aynı şekilde rakamları seçmek için [0-9] şeklinde kullanabilirsiniz. Aralığın sınırlarını sizler belirlersiniz. İllaki bunları kullanacaksınız diye bir şey söz konusu değildir.

] karakteri karakter sınıfının sonunda, karakter sınıfının sonlandığını belirtmek için kullanılır. Bunu karakter sınıfı içerisinde ayrıca kullanmak için escape işlemi ( \] ) uygulamak gerekir.

İşinizi kolaylaştırabilecek bazı yerleşik karakter sınıfları mevcuttur. Bunlardan bazıları;

\d veya [0-9]                           : Rakamlar

\s veya [\n\r\t]                         : Satır sonu, başlık ve tab karakterleri (whitespace karakterler de denir)

\D veya [^0-9]                                    : Rakamların dışındaki karakterler

\S veya [^\n\r\t]                      : Whitespace dışındaki karakterler

\w veya [A-Za-z0-9_]            : Alfanumerik karakterler ve _ karakteri

\W veya [^A-Za-z0-9_]          : Alfanumerik ve _ dışındaki karakterler

[\]\[!”#$%&'()*+,./:;<=>?@\^_`{|}~-]           : Noktalama işaretleri

- Alternatifler

|           : Alternatif ayracı. Örneğin a veya b karakterlerinı aramak için a|b şeklinde kullanım yapabilirsiniz.

()         : Alternatif parantezleri. Bunların içerisindeki semboller özel anlamlarıyla kullanılabilir. preg_match_all içerisinde kullanıldığında eşleşmenin sınırlarını belirlemeye yardımcı olur. Mesela bir desen içerisinde 2 farklı kural belirttiniz. İlk kuralla eşleşeni ayrı, ikinciyi ayrı şekilde almak istiyorsunuz. O zaman o kuralları ayrı ayrı parantez içerisinde yazmalısınız.

- Tekrarlar

Tekrarlanan karakterleri aramada kullanabileceğiniz birkaç özel karakter bulunmaktadır.

?          :0 veya 1 defa eşleşmeyi yakalar. Buradaki 0'a dikkat edin. Hiçbir eşleşme olmamasına rağmen bu karakter olumlu sonuç verecektir.

*          : 0'dan ∞'a kadar. Bir eşleşmenin hiç olmaması veya sonsuz sayıda olmasını belirten karakterdir.

+          : 1'den ∞'a kadar. Bir eşleşmenin en az bir defa veya sonsuz sayıda olmasını belirten karakterdir.

{n}      : N ile belirtilen miktarda eşleşme olması gerektiğini belirtir.

{n,m}  : En az n, en fazla m kadar eşleşme olması gerektiğini belirtir. Eşleşme miktarında ilk olarak büyük olan miktarı kontrol eder. Büyük olan miktar bulunamazsa azalarak sınır olarak belirttiğiniz alt limite kadar arama yapmaya devam eder.

{n,}     : En az n veya daha çok eşleşme olması gerektiğini belirtir.

- ? Karakterinin Özel Anlamı

? Karakteri tekrar sayısı olarak belirtilebildiği gibi, kendisi dışındaki bir tekrar sayısının yanında kullanıldığında belirtilen desene uyan en kısa eşleşmenin bulunacağını belirtir. Desenler, normalde her zaman en uzun eşleşmeyi yakalamaya çalışırlar.

- Niteleyiciler (modifiers)

Bunlar desenin dışına, kapsam parantezlerinin sonuncusunun yanına yazılırlar. Örneğin /desen/x şeklinde.

i           : Desene büyük-küçük harf hassasiyeti kazandırır. Daha tanınan tabiriyle case-insensitive özelliğini aktif eder.

m         : Başlangıç ve bitiş karakterlerinin, satır sonu karakterleriyle de eşleşmesini sağlar. Normalde desenler, aksi belirtilmediği müddetçe tek bir satır içerisinde arama yaparlar. Yani metinlerin sonunda yeni satıra geçmeyi sağlayan özel karakterlerle eşleşmezler ve desen o karaktere olan kısma kadar arama yapar. Bu özellik o karakteri de tanımasını ve böylece birden çok satıra sahip metinlerde arama yapabilmemizi sağlar.

s          : . özel karakteri, satır sonu-başı karakterlerini de yakalamaya başlar.

x          : Deseni çok satırlı şekilde yazmaya olanak sağlar.

u          : utf-8 desteği sağlar.

Regex Fonksiyonlarının İşlevleri

preg_match(desen,metin,eşleşenler) : Desene uyan ilk eşleşmeyi yakalar. Fonksiyon true/false (0/1) döndürür. Eşleşme sonunda bulunan değerler eşleşenler parametresinde belirtilen değişkene dizi halinde aktarılır.

preg_match_all(desen,metin,eşleşenler)        : Desene uyan tüm eşleşmeleri yakalar. Fonksiyon geriye toplam eşleşme sayısını döndürür.

preg_replace(desen,yenikısım,metin) : Desene uyan kısmı yakalar ve eşleşenleri yenikısımda belirtilen bölüme göre yeniden düzenler. Fonksiyon geriye değiştirilmiş metni döndürür.

Kullanım Örnekleri

$metin = "Bu yoğurdu sarımsaklasak ta mı saklasak, sarımsaklamasak ta mı saklasak?";

preg_match("/sarımsak/",$metin,$eslesme);

// Yalnızca "sarımsaklasak" kelimesindeki sarımsak kelimesini yakalar.

$metin = "tahribat.com'a hoşgeldiniz";

preg_match("/[^t]/",$metin,$eslesme);

// Yalnızca tahribat.com'un 2. karakteri olan a'yı yakalar.

$metin = "tahribat.com'a hoşgeldiniz";

preg_match_all("/[^t]/",$metin,$eslesme);

// Metnin bütünündeki t karakterleri hariç tüm karakterleri yakalar.

$metin = "fıs3tık2çı01şahap5";

preg_match_all("/\d/",$metin,$eslesme);

// Metnin içerisindeki 3 2 0 1 ve 5 karakterlerini yakalar.

$metin = "tahribat.com tahribat forum tahri_bat";

preg_match("/^tahribat$/",$metin,$eslesme);

// Hiçbir şeyi yakalamaz. Çünkü metin yalnızca tahribat kelimesinden oluşmuyor.

$metin = "tahribat";

preg_match_all("/^tahribat$/",$metin,$eslesme);

// tahribat kelimesini yakalar.

$metin = "tahribat.com forumları";

preg_match("/^tahri.*/",$metin,$eslesme);

// “tahribat.com forumları” metnini yakalar.

$metin = "tahribat.com forumları";

preg_match("/^tahri.+?/",$metin,$eslesme);

// "tahrib" kelimesini yakalar.

$metin = "tahribat.com forumları";

preg_match("/^tahri.{3}/",$metin,$eslesme);

// "tahribat" kelimesini yakalar.

$metin = "tahriBaT.com forumları";

preg_match_all("/[tb]/i",$metin,$eslesme);

// "t B T" karakterlerini ayrı ayrı yakalar.

$metin = "<b>Bu regex anlatımı</b> tahribat.com <b>için hazırlanmıştır.</b>";

preg_match("/<b>.*<\/b>/",$metin,$eslesme);

// "Bu regex anlatımı tahribat.com için hazırlanmıştır." metnini yakalar.

$metin = "<b>Bu regex anlatımı</b> tahribat.com <b>için hazırlanmıştır.</b>";

preg_match("/<b>.*?<\/b>/",$metin,$eslesme);

// "Bu regex anlatımı" metnini yakalar.

$metin = "<b>Bu regex anlatımı</b> tahribat.com <b>için hazırlanmıştır.</b>";

preg_match_all("/<b>.*?<\/b>/",$metin,$eslesme);

// "Bu regex anlatımı" ve "için hazırlanmıştır" metinlerini ayrı ayrı yakalar.

$metin = "tahribat.com site hack ve dosya warez";

$metin = preg_replace("/hack|warez/","paylaşım",$metin);

// "tahribat.com site paylaşım ve dosya paylaşım" olarak değiştirir

Bunlar bazı temel örnekler idi. Tabiki koskoca regex bunlardan ibaret değil. Ben bu yazıda temel bir giriş yapıp en azından kavramlar hakkında bilgi vermeye çalıştım. Kavramları öğrendikten ve bol bol desen yazıp kurcaladıktan sonra istediğiniz olasılıklarda sonsuz sayıda kombinasyon oluşturabilirsiniz. Bu tamamen sizin ihtiyacınız ve düşüncelerinizle sınırlıdır.

Tarih:
Hit: 1081316
Yazar: Austen



Yorumlar


Yorum yapabilmek için üye girişi yapmalısınız.

Yorumlar

smoker tarafından yazıldı. Tarih: 17/Tem/19 00:45
Çok güzel hazırlanmış, emeğinize sağlık hocam.