Bu yazımda C programlama dili ile nasıl Düzenli İfadeler (Regular Expressions) kullanabileceğinizi anlatacağım. Yazı düzenli ifadeler'i bildiğinizi farz alarak hazırlanmıştır.
Öncelikle C dili için düzenli ifadeler kütüphanesini edinmelisiniz. GNU C Library ile gelen regex kütüphanesini kullanacağız. Eğer GNU tabanlı bir işletim sistemi kullanıyorsanız libc6-dev paketini yüklemeniz yeterli olacaktır. MS Windows tabanlı bir işletim sistemi kullanıyorsanız regex kütüphanesinin Windows portunu MinGW'nin download sayfasından indirebilirsiniz.
GNU C Library sayesinde C ile regex kullanmak çok basittir. Programımıza başlamadan önce regex.h kütüphanesini dahil edelim ve main fonksiyonumuzu tanımlayalım. printf için stdio.h, exit için stdlib.h kullanıyoruz.#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
Derlenmiş düzenli ifademizi regex_t veritipi saklamaktadır. Öncelikle string şeklinde olan düzenli ifadeyi derlemeli ve daha sonra çalıştırmalıyız. Basit bir string ve şablon (pattern) belirleyelim. Ayrıca derleme ve çalıştırma fonksiyonlarımızın sonucunu saklayacak bir status belirleyelim.
/* derlenmiş düzenli ifademizi taşıyacak veritipi */
regex_t regex;
char *string = "Merhaba düzenli ifadeler!";
char *pattern = "d.*ifade";
int status;
Bundan sonra düzenli ifademizi kullanılmak üzere derleyeceğiz. Derleme işlemini int regcomp (regex_t *restrict compiled, const char *restrict pattern, int cflags) fonksiyonu yerine getirecek. İlk argümen veritipimiz, ikinci şablon stringimiz ve üçüncü argümen control flaglarını içermelidir. POSIX Regular Expressions flagarı şunlardır:REG_EXTENDED : Basit düzenli ifadelerdense gelişmiş düzenli ifadeleri kullanır.REG_ICASE : Büyük-küçük harf uyumunu yoksayar.REG_NOSUB : Bulunan değeri atama arrayını yoksayar.REG_NEWLINE : Şablonu birden fazla satırda arar.
Flagları öğrendikten sonra şablonumuzu derliyoruz. Biz herhangi bir değer ataması yapmayacağımızdan REG_NOSUB flagını kullanıyoruz. Fonksiyon eğer bağarılı bir şekilde çalışırsa 0 döner. Başarılı olamazsa bir uyarı mesajıyla birlikte programımız, EXIT_FAILURE değeriyle sonlanacak.
/* düzenli ifademizi derliyoruz */
status = regcomp (®ex, pattern, REG_NOSUB);
if (status != 0)
{
printf ("Şablon derlenemedi\n");
exit (EXIT_FAILURE);
}
Şimdi derlenen düzenli ifademizi stringimiz üzerinde çalıştırmaya geldi sıra. Bu işi int regexec (const regex_t *restrict compiled, const char *restrict string, size_t nmatch, regmatch_t matchptr[restrict], int eflags) fonksiyonu yerine getirecek. Fonksiyonun ilk argümeni regex derlemiş olduğumuz veritimiz, ikincisi düzenli ifadeyi çalıştıracağımız string, üçüncü; eğer veri yakalıyorsak yakalanacak veri adedi, dördüncü argümen; eğer veri yakalıyorsak yakalanan veri arrayı, beşinci argümen ise bazı seçenekleri içeren flagları alır. Bu flaglar şunlardır:REG_NOTBOL : String'in ilk satırını dikkate almaz.REG_NOTEOL : String'in son satırını dikkate almaz.
Fonksiyonun nasıl kullanılacağını öğrendikten sonra şimdi fonksiyonumuzu kullanalım. Biz herhangi bir yakalama kullanmayacağımız için nmatch değerini 0, matchptr arrayını NULL ve harhangi bir flag kullanmadığımızdan flagı 0 giriyoruz. Fonksiyon eğer bir eşleşme bulamazsa REG_NOMATCH değerini döner.
/* derlenmiş düzenli ifademizi stringimiz üzerinde çalıştırıyoruz */
status = regexec (®ex, string, 0, NULL, 0);
if (status == REG_NOMATCH)
printf ("Herhangi bir eşleşme bulunamadı\n");
else
printf ("Eşleşme bulundu\n");
Son olarak derlenmiş regex_t veritipimiz (regex)'i temizliyoruz ve main fonksiyonumuzu 0 döndürüyoruz.
/* derlenmiş düzenli ifademizi temizliyoruz */
regfree (®ex);
return 0;
Yukarıda anlatılan programın tam sürümü:
/**
* C ile Düzenli İfadeler
* reg_ornek_1.c
*/
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
/* derlenmiş düzenli ifademizi taşıyacak veritipi */
regex_t regex;
char *string = "Merhaba düzenli ifadeler!";
char *pattern = "d.*ifade";
int status;
/* düzenli ifademizi derliyoruz */
status = regcomp (®ex, pattern, REG_NOSUB);
if (status != 0)
{
printf ("Şablon derlenemedi\n");
exit (EXIT_FAILURE);
}
/* derlenmiş düzenli ifademizi stringimiz üzerinde çalıştırıyoruz */
status = regexec (®ex, string, 0, NULL, 0);
if (status == REG_NOMATCH)
printf ("Herhangi bir eşleşme bulunamadı\n");
else
printf ("Eşleşme bulundu\n");
/* derlenmiş düzenli ifademizi temizliyoruz */
regfree (®ex);
return 0;
}
Peki veri yakalamak istiyorsak?
Düzenli ifadelerin en önemli özelliklerinden biride veri yakalamaya olağan sağlamasıdır. Eğer programımızda veri yakalamak istiyorsak bir nmatch değeri (yakalanacak veri sayısı) ve bir regmatch_t veritipi (yakalanmış verileri tutan veritipi) arrayı tanımlamalıyız. Örnek olarak yakalacak 1 veri alıyorum. nmatch değerinin ilki tüm eğer eşleşme varsa tüm veriyi içereceğinden yakalanacak veriden bir fazla olmalıdır.
/**
* C ile Düzenli İfadeler
* reg_ornek_2.c
*/
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
/* derlenmiş düzenli ifademizi taşıyacak veritipi */
regex_t regex;
char *string = "Merhaba düzenli ifadeler!";
char *pattern = "^\\(M.*a\\) düzenli ifadeler!$";
size_t nmatch = 1 + 1;
regmatch_t regmatch[1];
int status;
/* düzenli ifademizi derliyoruz
* yakalama kullanacağımızdan REG_NOSUB
* flagını kaldırdık */
status = regcomp (®ex, pattern, 0);
if (status != 0)
{
printf ("Şablon derlenemedi\n");
exit (EXIT_FAILURE);
}
/* derlenmiş düzenli ifademizi stringimiz üzerinde çalıştırıyoruz
* daha önce girmediğimiz 3. ve 4. argümenleri giriyoruz */
status = regexec (®ex, string, nmatch, regmatch, 0);
if (status == REG_NOMATCH)
printf ("Herhangi bir eşleşme bulunamadı\n");
else
printf ("Yakalanan veri: \"%.*s\"\n",
regmatch[1].rm_eo - regmatch[1].rm_so,
&string[regmatch[0].rm_so]);
/* derlenmiş düzenli ifademizi temizliyoruz */
regfree (®ex);
return 0;
}
© 2008 Onur Aslan <onuraslan@users.sourceforge.net>
Yazı ve içerisinde yer alan kodlar GNU Genel Kamu Lisansı sürüm 3 şartları altında değiştirilebilinir, çoğaltılıp dağıtılabilinir.
0 yorum:
Yorum Gönder