Bu yazımda C# da harika bir regex örneği oluşturacağız , büyük bir heyecan içinde hemen senaryodan bahsedeyim :) Bir SMS sisteminizin olduğunu düşünün, insanlar size AD SOYAD ŞEHİR YAŞ ve NUMARA ' larını SMS olarak atacaklar siz bu yazıdan kullanıcının telefon numarasını ,numerik olmayan yazı içeren kısmı (yani AD SOYAD ŞEHİR) bulacaksınız ve de yaşını.Ayrıca yanlış sırada SMS atan (ör: AD SOYAD ŞEHİR NUMARA YAŞ) kullanıcı SMS 'ini de düzgün sıraya çevireceğiz.(NUMARA ve YAŞ alanları yer değiştirecek.)
Bunun için önce boş bir websitesi oluşturalım Defaul.aspx adında bir sayfası olsun,ve bahsettiğimiz senaryo için bir TextBox ,bir Button ve bir Label oluşturalım.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Regex Sample</title>
<meta http-equiv="content-type"
content="text/html;charset=utf-8" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox Height="40" Width="600px" runat="server" ID="message_box"></asp:TextBox>
<asp:Button runat="server" ID="create_btn" Text="Create" OnClick="create_btn_Click" />
<asp:Label runat="server" ID="alert_lbl" />
</div>
</form>
</body>
</html>
protected void Page_Load(object
sender, EventArgs
e)
{
}
protected void
create_btn_Click(object sender, EventArgs e)
{
alert_lbl.Text =
ProduceCorrectMessage(message_box.Text);
}
private string
ProduceCorrectMessage(string messageBodyText)
{
string correct_message = "";
try
{
}
catch
{
}
return correct_message;
}
Öncelikle şunu da belirteyim ki aynı işi Regex ile farklı şekillede yapmak mümkün ben aşağıdaki şekilde bir yol izleyeceğim.İlk olarak mesajdaki tüm boşlukları yok edeceğim ve daha sonra Türkiye için mobil operatörlerin 5XX XXX XX XX formatında numara üretiğini düşünerek bu formattaki numerik alanı yakalamaya çalışacağım.Aşağıdaki iki satır bunu anlatmakta.
try
{
string txt =
messageBodyText.Replace(" ", "");
string user_msisdn = Regex.Match(txt, @"5[0-9]{2}[0-9]{7}").Value;
"SEMA KUDU İSTANBUL 905546785609 20"
string step1 =
messageBodyText.Replace(user_msisdn, "");
string user_text = Regex.Match(messageBodyText, @"[A-z^şŞıİçÇöÖüÜĞğ\s]*").Value;
Hemen yeni regex'i anlatmaya çalışayım burda görüldüğü gibi A-z arasında yani küçük ve büyğh harfler dahil tüm alfabetik karakterleri bulabilir demektir. A-z den sonra gelen Türkçe alfabeye özgü olan harfler ise Türk.e karakterleri yakalayabilmek için eğer boyle yapmazsanız Regex defaultta İngilizce alabeyi baz alıyor ve türkçe karakter gördüğü anda ifadeyi match etmeyi kesiyor.Yani kısacası türkçe desteklemiyor :) Türkçe harfleri(büyük ve küçük dahil desteklemesi için ) ^şŞıİçÇöÖüÜĞğ ifadesini yazdık. gelelim sonda yer alan \s ifadesine bu da harfler arasında yani kelimeler arasında boşluk tab gibi whitespace karakerler olabilir demektir.[A-.....]* "*" ise bu kümenin ya hiç gelmeyeceğini ya da bir çok defa tekrarlayabileceğini ifade ediyor.
Gelelim yaş bulma adımına bu kısım diğerlerini göre biraz daha karışık çünkü 5XX XXX XX XX numara alanını ve yazı alanını çıkardığımızda numarasını 05XX... ya da 905XXX... şeklinde yazan kullanıcılar için geriye 90 20 ya da 0 20 ya da +90 20 yazısı kalıyor eğer kullanıcı numarasını doğru formatta yazmış ise zaten geriye sadece 20 kalıyor ama bu iyi senaryo :) Şimdi yaş çıkarımı yapalım .Bu arada kullanıcı yaşını numaradan önce yazar ise 20 0 , 20 90 ya da 20 +90 ifadeleri geriye kalabilir. Bu geriye kalan text üzerine yapacağımız işlemler için ExtractAge adına bir metod yazdım.
Geriye kalan text'deki tüm boşlukları ilk satırdaki kod ile siliyoruz.Sonra String.Substring ile ilk iki karakterini alıyoruz. Bu durum yaşını numarasından önce yazmış kullanıcılar için doğru oluyor sonraki if şartında bu durumun tersi ise yani yaşını msisdn'den sonra yazmış ise durumunu kontrol ediyor o zamanda sonra iki rakamı alıyoruz. İki hane almamızın sebebi kullanıcıların yaşının 2 haneli olmasını bekliyoruz :)
Aslında işlemin büyük bir kısmını halettik son olarak iki işlem yapıp doğru mesajı üreteceğiz.İlk olarak msisdn'ları ormatlayalım yani 5XXXXXXXXX şeklinde olan numarayı okunabilirlik açısında 05XX XXX XX XX şekline getirelim.
İkinci olarak yazı alanındaki(ad soyad şehir) gereksiz boşlukları teke indirelim.Yine bunun içinde bir regex kullanacağız daha önce whitespace karakterlerini temsil eden \s den faydalanacağız.
Şimdi düzgün mesajı elde edebiliriz.SMS'i doğru atanlanlar için bir sorun olmayacaktır :)
ProduceCorrectMessage metodunun son hali aşagıdaki gibi olacaktır.
Şimdi projemizi test edebiliriz aşağıda bir kaç test görüntüsü var.
Teşekkürler, sağlıkla , mutlulukla kalın.
Ne dinlemeli alanını unutmadım tabi :)
Gelelim yaş bulma adımına bu kısım diğerlerini göre biraz daha karışık çünkü 5XX XXX XX XX numara alanını ve yazı alanını çıkardığımızda numarasını 05XX... ya da 905XXX... şeklinde yazan kullanıcılar için geriye 90 20 ya da 0 20 ya da +90 20 yazısı kalıyor eğer kullanıcı numarasını doğru formatta yazmış ise zaten geriye sadece 20 kalıyor ama bu iyi senaryo :) Şimdi yaş çıkarımı yapalım .Bu arada kullanıcı yaşını numaradan önce yazar ise 20 0 , 20 90 ya da 20 +90 ifadeleri geriye kalabilir. Bu geriye kalan text üzerine yapacağımız işlemler için ExtractAge adına bir metod yazdım.
string step2 =
step1.Replace(user_text, "");
string user_age = ExtractAge(step2);
private string
ExtractAge(string user_age)
{
string CorrectAge = "";
try
{
user_age = user_age.Replace(" ", "");
CorrectAge = user_age.Substring(0, 2);
if (user_age.StartsWith("+") ||
user_age.StartsWith("0") || user_age.StartsWith("9"))
CorrectAge =
user_age.Substring(user_age.Length - 2, 2);
}
catch
{
//Log.Error(ex1.Message,
ex1);
}
return CorrectAge;
}
Geriye kalan text'deki tüm boşlukları ilk satırdaki kod ile siliyoruz.Sonra String.Substring ile ilk iki karakterini alıyoruz. Bu durum yaşını numarasından önce yazmış kullanıcılar için doğru oluyor sonraki if şartında bu durumun tersi ise yani yaşını msisdn'den sonra yazmış ise durumunu kontrol ediyor o zamanda sonra iki rakamı alıyoruz. İki hane almamızın sebebi kullanıcıların yaşının 2 haneli olmasını bekliyoruz :)
Aslında işlemin büyük bir kısmını halettik son olarak iki işlem yapıp doğru mesajı üreteceğiz.İlk olarak msisdn'ları ormatlayalım yani 5XXXXXXXXX şeklinde olan numarayı okunabilirlik açısında 05XX XXX XX XX şekline getirelim.
string formatted_msisdn = FormatMsisdn(user_msisdn);
private string
FormatMsisdn(string msisdn)
{
string FormattedMsisdn = "";
try
{
string m1 =
msisdn.Substring(0, 3);
string m2 =
msisdn.Substring(3, 3);
string m3 =
msisdn.Substring(6, 2);
string m4 =
msisdn.Substring(8, 2);
FormattedMsisdn = "0" + m1
+ " " + m2 + " " + m3 + " " + m4;
}
catch
{
//Log.Error(ex1.Message,
ex1);
}
return FormattedMsisdn;
}
string formatted_user_text =
DeleteRepeatedSpaces(user_text);
private string
DeleteRepeatedSpaces(string text)
{
string FormattedText = "";
try
{
FormattedText = Regex.Replace(text, @"\s+", " ");
}
catch
{
}
return FormattedText;
}
correct_message =
formatted_user_text + user_age + " " + formatted_msisdn;
private string
ProduceCorrectMessage(string messageBodyText)
{
string correct_message = "";
try
{
string txt =
messageBodyText.Replace(" ", "");
string user_msisdn = Regex.Match(txt, @"5[0-9]{2}[0-9]{7}").Value;
string step1 =
messageBodyText.Replace(user_msisdn, "");
string user_text = Regex.Match(messageBodyText, @"[A-z^şŞıİçÇöÖüÜĞğ\s]*").Value;
string step2 =
step1.Replace(user_text, "");
string user_age =
ExtractAge(step2);
string formatted_msisdn =
FormatMsisdn(user_msisdn);
string formatted_user_text =
DeleteRepeatedSpaces(user_text);
correct_message =
formatted_user_text + user_age + "
" + formatted_msisdn;
}
catch
{
//Log.Error(
ex1.Message, ex1);
}
return correct_message;
}
SEMA KUDU İSTANBUL 905546785609 20
SEMA KUDU İSTANBUL 20 +905546785609
Evet sevgili takipçilerim yaş ve telefon numarası doğru olmamakla birlikte :D bu yazımızın da sonuna geldik. Tam projeyi burada bulabilirsiniz.Teşekkürler, sağlıkla , mutlulukla kalın.
Ne dinlemeli alanını unutmadım tabi :)
Bu akşam o kadar çok sevaba girdinizki anlatamam. 2 gündür regex için japon alfabesi için regex arıyordum.verdiğiniz sitede buldum teşekkurler..
YanıtlaSilFaydalı olabildiysem ne mutlu, okuduğunuz için teşekkürler.
YanıtlaSilKodda arızalı kısımlar var Substring yapmak ileride sıkıntıya sokabilir. Regex'iniz iyi çalışmıyor.
YanıtlaSilMerhaba, ilginiz için teşekkürler,iyi çalışmıyor dediğiniz kısım neresidir acaba? Teşekkürler.
Sil