Değişkenler ve String İşlemleri adlı bölümlerde String sınıfı ve string bilgiler hakkında bilgi verilmiş olmakla birlikte bu bölümde Format() metodu ve String bilgiler üzerinde işlem yapılırken gerek duyulan StringBuilder sınıfından söz edilecektir.
Değişik tipteki bilgileri ekrana veya başka bir ortama yazarken biçimlemek istiyorsanız String sınıfının Format metodunu kullanabilirsiniz. Konsol uygulamalarında Write metodu ile ekrana yazarken biçimleme yapılabildiği için Format metodunu kullanmaya gerek yoktur.
Write() ve WriteLine() metodu kendisine parametre olarak verilen bilgiyi ekrana yazarken biçimleyebilmektedir. Bu işlemin nasıl yapıldığını anlatmak için aşağıda verilen kodda bilgi aktardığımız float değişkenin içeriğini WriteLine() metodu ile konsola yazdırdık.

float değişkenin içeriğini yazdırırken “{}” parantezlerin içine “0:F3” yazdık. Buradaki 0, WriteLine() metoduna parametre olarak verilen ilk değişkeni temsil etmektedir. F3’ün F’si bilginin float ve 3 ise virgülden sonra 3 hanenin olacağını işaret etmektedir. Bu konsol uygulaması derlenip çalıştırıldığında aşağıdaki gibi bir sonuç alınır.

Bu değişkene aktarmış olduğumuz sayısal bilgide virgülden sonra 4 hane bulunmaktadır. Yazdırma işlemi sırasında 3 hanenin olmasını istediğimiz için 4. hanede yuvarlama yapıldı. Formatlama karakteri olarak F3 yerine C3 kullanış olsaydık virgülden sonra yine 3 hane olurda ama bu kez sayının sonuna para birimi eklenir ve sayı üçer hanelere ayrılırdı.
Sayının sonuna para birimi eklenmeden üçer hanelere ayırmak istemiş olsaydık formatlama yaparken “N” harfini kullanırdık. Virgülden sonra 2 hanenin olmasını istiyorsanız formatlama karakteri olarak N2’yi kullanmalısınız.
Console.WriteLine("{0:N2}",Sayi);
Yukarıda N, C ve F gibi formatlama karakterlerini kullanarak biçimleme yaptık. İsterseniz kendiniz özel biçim veya formatlar hazırlayabilirsiniz. Bu işlemin nasıl yapıldığını görmek istiyorsanız aşağıda verilen konsol uygulamasını inceleyebilirsiniz. Bu konsol uygulaması derlenip çalıştırıldığında double tipindeki değişkene aktarılan bilgi üçer hanelere ayrılır.
double sayi = 12345678;
Console.WriteLine("{0:#,###}", sayi);
Yukarıda anlatılan formatlama karakterlerine ek olarak kullanabileceğiniz “X” ve “P” karakterlerin işlevini anlatmak için aşağıda verilen basit örmeği hazırladık. Sayısal bilgiyi 16 tabanlı olarak göstermek istediğinizde X, yüzde olarak ifade etmek istediğinizde ise “P” karakteri ile biçimleme yapabilirsiniz.

Format() Metodu İle Biçimleme Yapmak
Yukarıdaki sayfalarda Format() metodunu kullanmadan formatlama yaptık. İsterseniz aynı işlemleri Format() metodu ile yapabilirsiniz. Format metodu parametre olarak aldığı bilgiyi formatlayıp String olarak geriye göndermektedir. Bu nedenle bir string değişken tanımladık. Aşağıda verilen konsol uygulaması yukarıdaki ile aynı işleve sahiptir.
public static void Main()
{
double sayi = 123456.9876;
string str = String.Format("{0:#.###}", sayi);
Console.WriteLine(str);
}
Görüleceği üzere konu konsol uygulaması olunca Format() metoduna pek gerek yoktur. Format() metodu asıl Windows Forms projelerinde işe yaramaktadır. Format() metodu ile nasıl biçimleme yapıldığını anlatmak için forma bir TextBox yerleştirip aşağıda verilen kodu hazırladık. Bu kod işletildiğinde double değişkenin içeriği verilen biçim koduna göre biçimlenip TextBox’a aktarılır.
double sayi = 123456.9876;
string str = String.Format("{0:#.###}", sayi);
textBox1.Text = str;
Yukarıdaki sayfalarda Write() metodu ile ilgili olarak anlatılanlar Format() metodu için de geçerlidir. Bu nedenle Format() metodu aşağıdaki gibi kullanıldığında int değişkenin içeriğine para birimi eklenmiş ve üçer hanelere ayrılmış hali TextBox’a yazılır.
int sayi = 12345678;
string str = String.Format("{0:C0}", sayi);
textBox1.Text = str;
Tamsayı bilgileri biçimlemek istiyorsanız biçim kodunda “D” harfini kullanmalısınız. Aşağıda verilen örnekte içeriğini biçimlemek istediğimiz int değişkene 6 haneli bir sayı aktardık. Biçimleme karakteri olarak D8 kullandığımız için sayının başına 2 sıfır konulur.
int sayi = 123456;
string str = String.Format("{0:D8}", sayi);
textBox1.Text = str;
Format() metodu ile biçimlemek istediğimiz sayı 8’den fazla haneye sahip olsaydı veya D8 yerine D5 kullansaydık sayısal bilgide kesilme olmazdı. Aşağıda verilen ekran görüntüsü bu kodlar işletilip sayının formatlanıp TextBox’a aktarılması sağlandıktan sonra alındı.

Formatlama karakteri olarak E’yi kullanırsanız sayılar bilimsel gösterime dönüştürülür. Bilimsel gösterimde virgülden sonraki hane sayısını ayarlamak için hane sayısını “E” harfinin yanına yazmalısınız.
int Sayi = 123456;
string str = String.Format("{0:E4}", Sayi);
Format() metoduna 2. parametre olarak verdiğiniz sayının 16 tabanlı sayı sistemine dönüştürülüp ondan sonra string değişkene aktarılmasını istiyorsanız formatlama karakteri olarak X’i kullanmalısınız.
int Sayi = 65535;
string str = String.Format("{0:X}", Sayi);
textBox1.Text = str;
Bu satırlar bir metoda yazılıp işletilirse aşağıdaki gibi bir sonuç alınır. 10 tabanlı 65535 sayısı 16 tabanlı sayı sistemine dönüştürüldüğü zaman 4 hane yeterli olmaktadır. Bu durumda biçimleme kodu olarak “X5” kullanılmış olunsaydı sayının başına 0 eklenirdi.

Konunun iyice anlaşılmasını sağlamak için telefon numarasının başına şehirler arası kodu ekleyip Format() metodu ile biçimleyeceğiz. Bu amaçla int tipinde 2 değişken tanımlayıp birisine şehirler arası kodu, diğerine ise bir telefon numarasını aktardık.
int Kod = 312;
int Tel = 4353030;
string Str = String.Format("0-{0:N0}-{1:### ## ##}", Kod, Tel);
textBox1.Text = Str;
ToString() Metodu İle Biçimleme Yapmak
Bu kitapta hazırlanan basit örneklerde şimdiye kadar belki en çok kullanılan metot ToString(). Bu metot sayısal ve tarihsel bilgileri string bilgiye dönüştürüyordu. ToString() metodu ile dönüştürme işlemi dışında sayı ve tarih bilgilerini biçimleyip bir string değişkene veya TextBox’a aktarabilirsiniz. ToString() metodu ile biçimleme işleminin nasıl yapıldığını anlatmak için aşağıda verilen kodu hazırladık.
double Sayi = 1234.8765;
string str1 = Sayi.ToString("F3");
textBox1.Text = str1;
Bu kodda önce double tipinde bir değişken tanımlayıp bu değişken virgülden sonra 4 hanesi olan bir sayıyı aktardık. Ardından bu değişkenin içeriğini ToString() metodu ile biçimleyip string bir değişkene ve oradan TextBox’a aktardık.
ToString() metoduna biçim kodu olarak “F3” bilgisini verdiğimiz için sayının virgülden sonra 3 haneye sahip olması sağlanır. Aşağıda verilen ekran görüntüsünü forma bir TextBox yerleştirip yukarıda verilen satırları işlettikten sonra aldık.

ToString() metodu ile integer bir değişkenin içeriğini üçer hanelere ayırıp sonuna para birimini eklemek isteseydik aşağıdaki gibi kullanırdık.
int sayi = 1234567;
string Str = sayi.ToString("C0");
textBox1.Text = Str;
ToString() metoduna parametre olarak verilen C0’daki 0, virgülden sonraki hane sayısını işaret etmektedir. Hane sayısı 0 olarak verildiği için sayı kesirsiz olur. Bu kodu işletirseniz aşağıdaki gibi bir sonuç alırsınız.

Biçimleme karakteri olarak “C” yerine N’yi kullanırsanız sayı üçer hanelere ayrılır ama sonuna para birimi simgesi konulmaz.
int Sayi = 1234567;
string Str = Sayi.ToString("N0");
textBox1.Text = Str; // TextBox’a 1.234.567 aktarılır.
Söz konusu sayıyı yüzde(%) olarak göstermek istiyorsanız “P” biçim kodundan yararlanabilirsiniz. Sayısal bilgiyi ToString() metodu ile string bilgiye dönüştürürken 16 tabanlı sayı sistemine çevrilmesini istiyorsanız biçim kodu olarak X’i kullanmalısınız.
double Yuzde = 0.25;
int Sayi = 255;
string Str = Yuzde.ToString("P0"); //TextBox'a %25 aktarılır
textBox1.Text = Str;
Str = Sayi.ToString("X");
textBox2.Text = Str; // TextBox'a FF aktarılır
Str = Sayi.ToString("X4");
textBox3.Text = Str; // TextBox'a 00FF aktarılır
ToString() metodu ile biçimleme yaparken hazır biçim kodları yerine Format() metodunda olduğu gibi kendiniz özel biçim kodu hazırlayıp kullanabilirsiniz.
uint Tel = 3124353030;
string Str = "0-##-### ## ##";
textBox1.Text=Tel.ToString(Str); //TextBox’a 0-312-435 30 30 yazılır
StringBuilder Sınıfı
StringBuilder sınıfından yararlanarak dinamik yapıya sahip String değişkenler hazırlayıp bu değişkenler üzerinde istediğiniz işlemi yapabilirsiniz. String değişkenin içeriğini sıkça değiştirmeniz gerekiyorsa performans kazanmak için StringBuilder sınıfından yararlanabilirsiniz. String sınıfından yararlanılarak metin kopyalama, değiştirme ve ekleme işlemleri yapılırken her seferinde yeni bir değişken tanımlandığı için performans kaybı olmaktadır. Bu konuda bilgi vermek için aşağıda verilen kodu yazdık.
private void Form1_Click(object sender, EventArgs e)
{
string Adres = "Seçkin Yayıncılık ";
Adres += "Sağlık Sok. Sıhhiye-Ankara";
textBox1.Text = Adres;
}
Bu kodda önce string bir değişken tanımlayıp bilgi aktardık. Ardından bu string değişkene başka bilgiler ekledik. Bu koda bakıp string birleştirme işleminin basit olduğunu düşünebilirsiniz. String birleştirme işlemi için öncelikle bellekte geçici bir alan rezerve edilir. Ardından mevcut içerik bu geçici alana aktarılır. Devamında eklenecek bilgi geçici alandaki mevcut bilginin sonuna eklenir. Bu işlemden sonra birleştirilmiş 2 bilginin sığabileceği büyüklükte başka bir alan tahsis edilir ve geçici alandaki birleştirilmiş bilgiler yeni alana aktarılıp geçici alan serbest bırakılır.
String birleştirme işlemi StringBuilder sınıfından yararlanılarak yapıldığında bu işlemler oldukça hızlı gerçekleşmektedir. StringBuilder sınıfı System.Text adlı Namespace’te tanımlı olduğu için bu namespace’i kullanmak istediğinizi using deyimi ile belirtmeniz gerekir veya her seferinde bu namespace’in adını sınıf adının önüne eklemeniz gerekir. StringBuilder sınıfının yapıcı metodunun 6 değişik şekli bulunmaktadır.
StringBuilder Str = new StringBuilder();
Bu satır ile “Str” adında bir StringBuilder nesnesi hazırlanmış olunur. StringBuilder nesnesini bu şekilde tek satırda tanımlayıp oluşturmak yerine tanımlama ve new anahtar kelimesi ile oluşturma işlemlerini aşağıda yapıldığı gibi ayrı satırlarda yapabilirsiniz.
StringBuilder Str;
Str = new StringBuilder();
StringBuilder nesnesi hazırlanırken başlangıç değeri aktarılabilinir. Başlangıç değeri olarak aktarılmak istenen bilgi yapıcı metoda parametre olarak verilmelidir.
StringBuilder Str = new StringBuilder("Fenerbahçe");
Bu şekilde tanımlayıp ilk değer aktardığınız StringBuilder nesnesinin içeriğini başka amaçlar için kullanabilirsiniz. Aşağıda verilen kod işletildiğinde StringBuilder nesnesinin veya değişkenin içeriği TextBox’a aktarılır.
string Takim = "Fenerbahçe";
StringBuilder Str = new StringBuilder(Takim);
textBox1.Text = Str.ToString();
newanahtar kelimesi ile StringBuilder nesnesi hazırlarken başlangıç değeri aktarılmayan StringBuilder nesnesine bilgi aktarma Append() metodu ile yapılmaktadır. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe");
Append() metodunu arka arkaya kullanıp StringBuilder nesnesine istediğiniz kadar bilgi aktarabilirsiniz. StringBuilder nesnesine aktarılan bilginin uzunluğunu öğrenmek istiyorsanız Length özelliğine bakabilirsiniz.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe");
textBox1.Text = Str.ToString();
textBox2.Text = Str.Length.ToString();
StringBuilder nesnelerinin başlangıç kapasitesi 16’dır. 16 karakterden daha fazla bilgi aktarıldığında kapasite otomatik olarak ikiye katlanır. StringBuilder nesnesinin kapasitesi Capacity özelliğinde saklanmaktadır. Aşağıda verilen kod işletildiğinde StringBuilder nesnesinin kapasitesi 3. TextBox’a aktarılır.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe");
textBox1.Text = Str.ToString();
textBox2.Text = Str.Length.ToString();
textBox3.Text = Str.Capacity.ToString();
Bu sırada StringBuilder nesnesi 10 karakter kadar bilgi içerdiği için kapasite 16’dır. Eğer aşağıda yapıldığı gibi Append() metodu tekrar kullanılıp başka bilgiler de aktarılırsa kapasite önce 32, gerekiyorsa 64 veya daha fazla olur.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe");
Str.Append(" Spor Kulübu");
Bu şartlarda StringBuilder nesnesinin Length özelliği 22 ve kapasitesi ise 32 olur. StringBuilder nesnesine 32’den fazla sayıda karakter aktarılırsa kapasite 64 olur. StringBuilder nesnesinin kapasitesini kendiniz arttırmak istiyorsanız EnsureCapacity() metodunu kullanabilirsiniz. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe Spor Kulübü");
Str.EnsureCapacity(50);
textBox1.Text = Str.ToString();
textBox2.Text = Str.Length.ToString();
textBox3.Text = Str.Capacity.ToString();
EnsureCapacity() metodunun kullanıldığı sırada StringBuilder nesnesine toplam 22 karakter aktarılmıştı. Dolayıyla kapasite 32 idi. EnsureCapacity() metoduna parametre olarak 50 verince kapasite 64 oldu. Çünkü bu nesnelerin kapasiteleri 16, 32, 64, 128 gibi artmaktadır. StringBuilder nesnesini new anahtar kelimesi ile nesne hazırlarken kapasitesini belirtebilirsiniz. StringBuilder nesnesi aşağıdaki gibi hazırlandığında kapasitesi 10 olur.
StringBuilder Str = new StringBuilder(10);
int Kapasite = Str.Capacity;
textBox1.Text = Kapasite.ToString();
Bu şekilde hazırlanan StringBuilder nesnesine 10 karakterden daha fazla bilgi aktarılması halinde kapasite 20, 40 gibi kendiliğinden ikiye katlanır. StringBuilder nesnesinin kapasitesini belli bir değerle sınırlamak veya maksimum kapasitesini belirtmek istiyorsanız bu değeri 2. parametre olarak vermeniz gerekir. StringBuilder nesnesi aşağıdaki gibi hazırlanırsa kapasite en fazla 20 olabilir.
StringBuilder Str = new StringBuilder(10, 20);
Bu şartlarda StringBuilder nesnesine 20 karakterden fazla bilgi aktarılırsa hata meydana gelir. StringBuilder nesnesi hazırlanırken maksimum kapasitesi belirtilmediği zaman bunun 2147483647 olduğu varsayılır. Append() metodu veya başka bir teknikle StringBuilder nesnesine bilgi aktarmadan önce maksimum kapasite hakkında bilgi edinmek istiyorsanız MaxCapacity özelliğine bakabilirsiniz. Bu işlem için aşağıda verilen basit örneği hazırladık. Kullanıcı forma yerleştirdiğimiz “Ekle” adlı düğmeyi tıkladıkça TextBox’ın mevcut içeriği StringBuilder nesnesine eklenecektir.

Insert() ve Remove() Metotları
Append() metodu bilgiyi StringBuilder nesnesinin mevcut içeriğinin sonuna eklemektedir. Aktarma işlemini nesnenin sonuna değil de herhangi bir yerine yapmak istiyorsanız Insert() metodunu kullanmalısınız. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz.
StringBuilder Str = new StringBuilder();
Str.Append("Fenerbahçe Kulübü");
textBox1.Text = Str.ToString();
Str.Insert(11, "Spor ");
textBox2.Text = Str.ToString();
StringBuilder nesnesine bilgi aktarma işleminin kaçıncı karakterden itibaren yapılmasını istiyorsanız bunu Insert() metoduna 1. parametre olarak vermelisiniz. Bu satırlar işletildiğinde aşağıdaki gibi bir sonuç alınır.

StringBuilder nesnesinin mevcut içeriğinin bir kısmını silmek istiyorsanız Remove() metodunu kullanabilirsiniz. Remove() metodu ilk parametre olarak silme işleminin başlayacağı yeri istemektedir. Remove() metodu aşağıdaki gibi kullanıldığında nesnenin mevcut içeriğinin 12. karakterden itibaren 4 karakteri silinir.
StringBuilder Str = new StringBuilder();
Str.Append("Efes Pilsen Spor Kulübü");
textBox1.Text = Str.ToString();
Str.Remove(12, 4);
textBox2.Text = Str.ToString();
StringBuilder nesnesinin mevcut içeriğinin bir kısmını başka bir bilgi ile değiştirmek istiyorsanız Replace() metodunu kullanmalısınız. Replace() metodunun nasıl kullanıldığını aşağıda görebilirsiniz. Bu kod işletildiğinde StringBuilder nesnesinin mevcut içeriğindeki “Futbol” kelimesi “Basketbol” ile değiştirilir.
StringBuilder Str = new StringBuilder();
Str.Append("Futbol Milli Takımı");
textBox1.Text = Str.ToString();
Str.Replace("Futbol", "Basketbol");
textBox2.Text = Str.ToString();
AppendFormat() Metodu
Yukarıda hazırlanan StringBuilder nesnesine her seferinde karaktersel bilgi aktardık. Ancak isterseniz başka tip bilgileri bu nesne yani değişkenlere aktarabilirsiniz. Çünkü StringBuilder nesneleri her türlü bilgiyi kabul etmektedir.
int Sayi1 = 255;
double Sayi2 = 321.543;
bool Bool1 = false;
StringBuilder Str = new StringBuilder();
Str.Append(Sayi1);
Str.Append(Sayi2);
Str.Append(Bool1);
textBox1.Text = Str.ToString();
Bu kod işletildiğinde StringBuilder nesnesine aktarılmış olan bütün bilgiler TextBox’a yazılır. Ancak bu şekilde tanımlanıp bilgi aktarılan StringBuilder nesnesinin içeriğini biçimlemek istiyorsanız bilgileri StringBuilder nesnesine AppendFormat() metodu ile eklemeniz gerekir. Bu metodun nasıl kullanıldığını aşağıda görebilirsiniz.
int Sayi = 321543;
string bicim = "{0:C0}";
StringBuilder Str = new StringBuilder();
Str.AppendFormat(bicim, Sayi);
textBox1.Text = Sayi.ToString();
textBox2.Text = Str.ToString();
Bu kodda önce int tipinde bir değişken tanımlayıp bilgi aktardık. Ardından string bir değişken tanımlayıp bu değişkene Format() ve ToString() metotları ile formatlama yaparken kullanılan format karakterlerini aktardık.
inttipindeki değişkenin içeriğini para birimi gibi görüntülemek istediğimiz için bu string değişkene “{0:C0}” bilgisini aktardık. int tipindeki bu değişkenin içeriğini üçer hanelere ayırmak istemiş olsaydık biçim kodu olarak "{0:N0}" bilgisini kullanırdık.
Biçim kodu içeren string değişkeni tanımladıktan sonra AppendFormat() metodu ile hem int değişkeni hem de biçim kodu içeren string değişkeni aktardık. Çünkü AppendFormat() metodu 1. parametre olarak aldığı biçim kodunu 2. parametrede belirtilen bilgi ile birlikte StringBuilder nesnesine aktarmaktadır.Bu kod işletildiğinde aşağıdaki gibi bir sonuç alınır.

Şimdi ise AppendFormat() metodu ile birden fazla bilgiyi formatlayıp StringBuilder nesnesine aktaracağız. Bu amaçla biçim kodu içeren 2 ayrı değişken tanımladık. İlk biçim kodu ile ilgili değişkenin içeriğini üçere hanelere ayıracağız. 2. biçim kodu ise kesirli sayının virgülden sonra 2 haneye sahip olmasını sağlayacağız.
int Sayi1 = 3215432;
double Sayi2 = 1234.8765;
string Bicim1 = "{0:N0}";
string Bicim2 = " {0:F2}";
StringBuilder Str = new StringBuilder();
Str.AppendFormat(Bicim1, Sayi1);
Str.AppendFormat(Bicim2, Sayi2);
textBox1.Text = Sayi1.ToString();
textBox2.Text = Sayi2.ToString();
textBox3.Text = Str.ToString();
Bu kodu bir metoda yazıp işletirseniz aşağıdaki gibi bir sonuç alırsanız. StringBuilder nesnesinde bu 2 bilginin birbirine bitişik durmasını engellemek için 2. biçim kodunun başına birkaç boşluk ekledik.

Konunun iyice anlaşılmasını sağlamak için şimdi object tipinde bir dizi değişken tanımlayıp bu değişkenin elemanlarına farklı tipe sahip bilgiler aktarıp bu dizi değişkenin içeriğini AppendFormat() metodu ile StringBuilder nesnesine aktaracağız. Bu amaçla ilk olarak aşağıdaki satırlar ile object tipinde 3 elemanlı bir dizi değişken tanımlayıp elemanlarına bilgi aktardık.
object[] Dizi = new object[3];
Dizi[0] = "Seçkin Yayıncılık";
Dizi[1] = 312;
Dizi[2] = 4353030;
Object tipindeki dizi değişkeni bu şekilde tanımladıktan sonra formatlama kodlarını aktarmak üzere bir string değişken tanımlayıp içeriğini aşağıdaki gibi düzenledik.
string bicim="{0,20} 0-{1:N0}-{2:### ## ##}";
AppendFormat() metodu ile içeriğini StringBuilder nesnesine aktarmak istediğimiz object tipindeki dizi değişken 3 elemana sahip olduğu için “{}” parantezleri içinde 3 biçim koduna yer verdik. Sıra nosu 0 olan ilk biçim kodunda herhangi bir biçimleme yapılmıyor ancak 20 karakterlik yer ayrılmaktadır.
İlk biçim kodundan sonra kullanılan “0-“ sayesinde telefon numarasının başına ‘0-’ yazılması sağlandıktan sonra şehirlerarası kodu işaret etmek üzere 2. biçim kodu hazırladık. 3. biçim kodunda belirtilen telefon numarası 3-2-2 şekilde düzenlenmektedir.

Biçim kodunu hazırladıktan sonra StringBuilder nesnesi hazırladık ve AppendFormat() metodu ile object tipindeki değişkenin içeriğini StringBuilder nesnesine aktardık.
Düzenli İfadeler
Düzenli ifadeler(regular expressions) konusu daha çok web uygulamaları ile ilgili olsa bile C# uygulamalarında kullanıcının girdiği veya değişik kaynaklardan edinilen bilgileri kontrol ederken işlevsel olmaktadır. Örneğin değişik kaynaklardan elde edilen bir metindeki telefon numaralarının veya mail adreslerinin kurallara uygunluğunu test ederken düzenli ifadelerle ilgili sınıflardan yararlanabilirsiniz. Düzenli ifadeler konusu 2-3 sayfada anlatılacak bir konu değildir. Burada amacımız bu konuya dikkatinizi çekmekten ibarettir.
Uzun uzun bilgi vermek yerine hemen basit bir örnek hazırlayacağız. Bu amaçla forma bir TextBox ve ListBox yerleştirdik. TextBox’a yazılacak bilginin içinde mail adresi olarak değerlendirilecek bilgileri araştıracağız.
Düzenli ifadeler veya kısaca Regex ile ilgili sınıflar System.Text.RegularExpressions’de tanımlı oldukları için bu Namespace’i using bloğunda koda dahil ettik. Ardından text bilgileri içinde mail adresi ararken kullanmak üzere aşağıdaki gibi bir düzenli ifade hazırladım(daha doğrusu bu regex Visual Studio ile hazır olarak gelmektedir).
String pattern=@"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
Bu ifadenin nasıl oluşturulduğu ve bu ifadelerde kullanılan karakterlerin anlamı konusuna daha sonra kısaca değineceğiz. Bu şekilde düzenli ifadeyi string değişkene aktardıktan sonra Regex sınıfının Matches() metodundan yararlanıp bir MatchCollection nesnesi hazırladık. Matches() metodu araştırmaya konu edilecek metni ve düzenli ifadeyi parametre olarak almaktadır.
private void Form1_Click(object sender, EventArgs e)
{
string pattern = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
MatchCollection koleksiyon = Regex.Matches(textBox1.Text, pattern);
}
Bu kodun çalıştırıldığı sırada TextBox’a yazılıp ve e-Mail olarak değerlendirilecek bilgiler alınıp MatchCollection nesnesine aktarılır. TextBox’ta e-mail formatına uygun hiç bilgi yoksa bu koleksiyonun eleman sayısı 0 olur. Bu kodu aşağıdaki gibi düzenlediğinizde TextBox’a yazılanların taranıp düzenli ifadenin rehberliğinde araştırılması işleminin seyri hakkında bilgi alabilirsiniz.
private void Form1_Click(object sender, EventArgs e)
{
string pattern = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
MatchCollection koleksiyon = Regex.Matches(textBox1.Text, pattern);
if (koleksiyon.Count == 0)
MessageBox.Show("Mail adresine hiç rastlanmadı");
else
{
int sayi = koleksiyon.Count;
MessageBox.Show(sayi.ToString() + " adet mail adresi bulundu");
}
}
Şimdi TextBox’ın içeriğinin yukarıda verilen düzenli ifadeye uygun kısımlarını ListBox’a aktaracağız. Bildiğiniz gibi koleksiyonların içeriğini elde etmenin en pratik yöntemi foreach döngüsü hazırlamaktır.
private void Form1_Click(object sender, EventArgs e)
{
string pattern = @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
MatchCollection koleksiyon = Regex.Matches(textBox1.Text, pattern);
listBox1.Items.Clear();
if (koleksiyon.Count == 0)
MessageBox.Show("Mail adresine hiç rastlanmadı");
else
{
foreach (Match eleman in koleksiyon)
{
listBox1.Items.Add(eleman.Value);
}
}
}
Regexsınıfının Matches() metodu ile hazırlanan MatchCollection nesnesine aktarılan bilgilerin veya elemanların içerikleri Value özelliğinde saklanmaktadır. MultiLine özelliğini true yaptığımız TextBox’a birkaç adres ve mail adreslerini karışık olarak yazıp yukarıda verilen kodu işletince aşağıdaki gibi bir sonuç aldık.

Şimdi benzer örneği web sitesi adresi için yapacağız. Kullanıcıdan Web sitesinin adresini girmesini isteyeceğiz. Girdiği web sitesinin adresinin geçerli olup olmadığını araştıracağız. Bu araştırma web sitesinin hayali olup olmadığı ilgili olmayıp yalnızca yazım biçimi yönünden bir değerlendirme yapılacaktır.
private void Form1_Click(object sender, EventArgs e)
{
string pattern = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
MatchCollection koleksiyon = Regex.Matches(textBox1.Text, pattern);
if (koleksiyon.Count == 0)
{
MessageBox.Show("web sitesi adresiniz geçersiz");
}
}
Yukarıda MatchCollection nesnesini hazırlarken Regex sınıfının örneğini hazırlamaya gerek duymadık. Çünkü Matches() metodu statik bir metottur. İsterseniz aşağıda yapıldığı gibi önce Regex nesnesi hazırlayıp ondan sonra MatchCollection nesnesini hazırlayabilirsiniz.
private void Form1_Click(object sender, EventArgs e)
{
string pattern = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
Regex rg = new Regex(pattern);
MatchCollection koleksiyon = rg.Matches(textBox1.Text);
if (koleksiyon.Count == 0)
{
MessageBox.Show("web sitesi adresiniz geçersiz");
}
}
Konunun iyice anlaşılması için şimdi başka bir örnek hazırlayacağız. Hazırlayacağımız örnekte kullanıcıdan tarih isteyeceğiz. Kullanıcının girdiği tarih geçersiz ise tekrar girmesini isteyeceğiz. Hazırladığımız regex ifadesine göre GG/AA/YYYY formatında girilmeyen bilgilerin geçersiz olduğuna karar verilir.
private void Form1_Click(object sender, EventArgs e)
{
string pattern= @"((0[1-9])|([12][0-9])|(3[0-1]))(/)(0?[1-9]|1[0-2])(/)([12][0-9][0-9][0-9])";
Regex rg = new Regex(pattern);
MatchCollection koleksiyon = rg.Matches(textBox1.Text);
if (koleksiyon.Count == 0)
{
MessageBox.Show("Girdiğiniz tarih bilgisi geçersiz");
}
}
Şimdi bu regex ifadesini biraz açacağız ve nasıl hazırladığımızı anlatacağız. Bu ifade temelde 3 parçadan meydana gelmekte ve ilk parça tarihin gün kısmını kontrol etmektedir. Ayrıca ifadenin ilk kısmı kendi arasında 3 parçadan meydana gelmektedir. İfadenin gün bilgisini kontrol eden kısmı aşağıda verildi.
((0[1-9])|([12][0-9])|(3[0-1]))
İfadenin ilk parçasının ilk kısmı gün bilgisinin ilk hanesini(yani sıfır hanesi) kontrol etmektedir. Bildiğiniz gibi gün bilgisinin ilk hanesi 0 ise 2. haneye 0 ile 9 arasında değişen rakamlardan birisi yazılabilmektedir.
(0[1-9]) – ifadenin gün bilgisini kontrol eden ilk kısmı.
Bu Regex ifadesinin ilk parçasının 2. kısmı ise gün bilgisinin 2. hanesini kontrol etmektedir. Bildiğiniz gibi gün bilgisinin ilk hanesi 1 ise 2. hane yine 0 ile 9 arası bir değer olabilmektedir.
|([12][0-9]) -- ifadenin gün bilgisini kontrol eden ikinci kısmı.
Gün bilgisinin ilk hanesi 3 ise 2. hane 0 veya 1 olabilmektedir. Bu kontrolü ise yukarıda verilen ifadenin ilk parçasının 3. kısmı yapmaktadır. İfadenin gün kısmı ile ilgili bu kısımlar “|” karakteri ile birleştirilmektedir. Burada amacımız düzenli ifadelerin işlevlerini hatırlatmak olduğu için regex ifadelerin kuralları ve karakterleri hakkında bilgi veremiyoruz.
(3[0-1]) - ifadenin gün bilgisini kontrol eden üçüncü kısmı.