Bireysel Mesaj Gösterim Modu

Görüntülenme: 30712
RegEx ve .NET
2007/08/20 5:42
Bildir! Alıntı ile cevap yaz Oyla! (0 oy)

VB.NET kullanılarak standart "Bul-Değiştir" işlemleri için, "String" türündeki bir değişkenin metotlarından yararlanılabilir.

Dim strMetin1 As String = "Mustafa Birgin ve Takıntıları"
Dim strMetin2 As String = strMetin1.Replace("Mustafa", "M.") 

Bunun sonucunda,
strMetin2 = "M. Birgin ve Takıntıları"
olur.

Ancak diyelim ki, bir metin içerisinde kullanılan ve uzunluğu bilinmeyen bir ifadeyi, farklı amaçlarda kullanmak için, yukarıdaki yöntem çok yetersiz kalabilir. Örnek olarak, metin içerisinde geçen, [link:Adres] değerini gerçekte HTML linki olarak elde etmek için özel fonksiyonlar yazmak gerekebilir.

İşte bugün, öyle bir duruma geldim ve özel fonksiyonun nasıl olabileceğini düşündüm... Daha önceden, VB6 'da basit bir yapı geliştirmiştim; onu buraya uyarlayabilirdim... Düşünmeye devam ettim... 

Daha önce öğrendiğim, FrontPage 2003 'te yer alan Normal İfadeler 'i düşündüm... Sonra, bu fonksiyonları internette bulabileceğimi düşündüm ve "Normal Expressions" anahtar kelimesiyle arama yaptım. Daha iyi bir sonuç, "Regular Expressions" anahtar kelimesiyle karşıma çıktı.

Ve, öteden beri .NET kütüphanelerinde karşılaştığım ve ürktüğüm RegEx 'in aslında Regular Expression ifadesinin kısaltılmışı olduğunu anladığımda hayrette kaldım.  

Bu sefer RegEx 'i araştırmaya başladım; zira metin işlemlerinde büyük rahatlık sağladığını ve şu anda istediğim işlemi bununla yapabileceğime inanıyordum.

Ve işte, şimdi, bir taraftan öğrendiklerimi, diğer taraftan buraya yazıyorum. 


Dim userName As String = "Birgin, Mustafa"
Dim re As New RegEx( "(\w+),\s(\w+)" )
userName = re.Replace( userName, "$2 $1" )
Response.Write( userName )

Yukarıdaki kodlamada sonucunda, sayfaya "Mustafa Birgin" ifadesi yazılacaktır.

() içerisindeki ifade ayrı bir grup gibi değerlendirilebilir. Yani yukarıdaki  "(\w+),\s(\w+)" deseninde bir kelime "(\w+)" devamında ", " (virgül ve boşluk) ",\s" ve ardından yine bir kelime "(\w+)" gelmektedir. Daha sonra, bu desen, userName değişkenine uygulanmakta ve "$2 $1" grup temsilcileriyle, grup elemanlarının yerleri değiştirilmektedir. Yani, "$2" 2. grubu (Mustafa) ve "$1" 1. grubu (Birgin) temsil etmektedir. 
Genel olarak "$N", N. parantez grubunu ifade eder (N, pozitif bir sayı). Not olarak, "$0" desene uygun tüm metni ifade eder.

Dolayısıyla, userName="Mustafa Birgin" olacaktır.

Şimdi, kullanılan özel karakterlerin anlamına bakalım...

.

Match any character except newline

Herhangi bir karakter (yeni satır hariç)

\w

Match any alphanumeric character

Herhangi bir sayısal olmayan karakter (word)

\s

Match any whitespace character

Boşluk karakteri (space)

\d

Match any digit

Herhangi bir rakam (digit)

\b

Match the beginning or end of a word

Bir kelimenin başı veya sonu (begin)

^

Match the beginning of the string

Satır başı

$

Match the end of the string

Satır sonu

 

Ve daha başka karakterler...

*

Repeat any number of times

Herhangi sayıda

+

Repeat one or more times

Bir veya daha fazla

?

Repeat zero or one time

Sıfır veya daha fazla

{n}

Repeat n times

n defa

{n,m}

Repeat at least n, but no more than m times

n ve üzeri; ancak m 'den daha büyük değil

{n,}

Repeat at least n times

En az n defa

 

Ve negatif durumlar...

\W

Match any character that is NOT alphanumeric

Herhangi bir karakter; fakat sayısal olmayan değil. (Yani sayısal.) :)

\S

Match any character that is NOT whitespace

Herhangi bir karakter; fakat boşluk değil

\D

Match any character that is NOT a digit

Herhangi bir karakter; fakat rakam değil

\B

Match a position that is NOT the beginning or end of a word

Herhangi bir karakter; fakat satır başında ya da satır sonunda değil

[^x]

Match any character that is NOT x

Herhangi bir karakter; fakat x değil (Yani x dışında bir karakter.)

[^aeiou]

Match any character that is NOT one of the characters aeiou

Herhangi bir karakter; fakat aeiou değil (Yani a,e,i,o,u dışında bir karakter)

Özel karakterlerin anlamını iptal etmek için önüne "\" karakteri konulur. Örneğin "\^" ya da "\$" gibi.

Ve örnekler...

  • \bbirgin\b
    "birgin" kelimesini bulur; mbirgin, ayrı bir kelime olmadığı için, eşleşmez.
  • \bBen\b.*\bBirgin\b
    "Ben Mustafa Birgin" ifadesiyle eşleşebilir.
  • \b\w{5,6}\b 
    5 veya 6 karakterli kelimeler
  • ^\w*
    Satırdaki ilk kelime
  • (\d{1,3}\.){3}\d{1,3}
    IP adresi (basit yöntem)
  • \b(\w+)\b\s*\1\b
    Tekrarlanan kelimeler
  • \b\w+(?=gin\b)
    "gin" ile biten bir kelimenin ön kısmı.
  • \d{3}(?!\d)
    3 rakam ve sonrasında rakam olmayan bir karakter.
  • (?<=<(\w+)>).*(?=<\/\1>)
    HTML tag (im) arasındaki metin
  • \b\d\d\d-\d\d\d\d ya da \b\d{3}-\d{4}
    7 rakamlı telefon
  • \b\w{6}\b
    6 karakterli bir kelime

Hayli uzun sürdü! Başlarda bu kadar uğraşacağımı bileydim, başlar mıydım; bilemiyorum.
Sanırım kendi özel fonksiyonumu yazmayı yeğlerdim; ama esnek olmazdı tabi! 
Ama şunu söylemeliyim ki, incelediğim kaynaklardan, çok az şey yazdım. Yani, çok daha fazlası var. Gerisi size kalmış... 

Derseniz ki, "Yazmak istediğin fonksiyon hani?"
Derim ki, "Bu bilgileri sindirmeden, kullanabileceğimden emin değilim! Şu an kafam karışık; beynim bunları kavramaya çabalıyor demek ki!"

Nasıl, başlarda dediğim gibi, önceden ürktüğüm kadar var mıymış?
Bence, yokmuş!

Yararlı olması dileğiyle...

---------------------------------
M. Birgin (Ağustos 2007)

Yararlanılan Kaynaklar:
http://aspnet.4guysfromrolla.com/articles/022603-1.aspx
http://www.codeproject.com/dotnet/RegexTutorial.asp


Şimdi de yeni bir ihtiyaç hasıl oldu. :P

RegEx.Replace metodunda, uygun tüm değerler topluca değiştirilmektedir. Oysa, ben bunları bireysel olarak değerlendirmek istiyorum. Yani, filtreye uygun değerleri, standart bir değerle değiştirmek yerine; her bir değeri ayrı ayrı işlemek istiyorum.
Ama yazık ki, RegEx 'in aralık tanımlamaları yok (ya da ben karşılaşmadım :P).
Yani şuradan şuraya kadar, uygun değer var mı, diye bakamıyorum.

Buna bir çözüm, metnin bir bölümü yeni bir değişkene aktarılarak, yeni değişken RegEx ile etkileşebilir.
Bu durumda, tüm değerlerin işlenmesi için, bir döngü oluşturulması gerekir.

Ya da, RegEx 'te uygun değerlerin bireysel olarak değerlendirilmesine olanak sağlayan MatchEvaluator sınıfı kullanılabilir.

Araştırmalarım sonucunda, oluşturduğum ve ihtiyacımı karşılayan örnek kullanım aşağıdadır.

-----------------------------

 Protected Sub btnRun_Click(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim strMetin1, strMetin2 As String
        strMetin1 = "<ul><li>Birinci Madde </li><li>İkinci Madde</li><li>Üçüncü Madde</li></ul>"       
       
        Dim MEvl As New MatchEvaluator(AddressOf MevlProcess)

        strMetin2 = Regex.Replace(strMetin1, "<li>(.*?)</li>", MEvl)
               
    End Sub

   
    Function MEvlProcess(ByVal m As Match) As String
        Static i As Integer
     
        i = i + 1
             
        Return "<li ID='ref" & i & "'>" & m.Groups(1).Value & "</li>"
               
    End Function

-----------------------------


Ve işte, metin içerisinde [link:Adres] ibaresinin geçmesi durumunda, bunu normal HTML linkine dönüştüren kullanım:

Dim strHTML As String = txtHTML.Text
If Regex.IsMatch(strHTML, "\[link:(.*?)\]") = True Then
    strHTML = Regex.Replace(strHTML, "\[link:(.*?)\]", "<a href='$1'>$1</a>)
End If

Olay budur yani! :P


"Regular Expressions" konusunu hayli kapsamlı işleyen ve bu konuya adanmış bir site: http://www.regular-expressions.info/

Sitede, "Regular Expressions", çok sayıda teknolojiye göre (.NET, JavaScript, VBScript, Visual Basic 6, XMLSchema, Delphi, Java, C/C++, Perl, PHP, Phyton, ...) örneklenmektedir.

İngilizce kelime ezberleme oyunu: vav.mbirgin.com
Abonelik Bilgisi Abonelik
Kullanıcı Adı:
Parola:
Bilgi Hatırlatma Yeni Üyelik
İletişim | Kullanım Şartları | Reklam Bilgileri | Tüm Üyeler | Ne Nasıl Yapılır? | Arama | RSS | Twitter | Facebook | Youtube

Son Üyeler: Gakk, busbus, siyamiaytar, 1234123123123, Siyami,
Son Oturumlar: