|
Bu yazımızda Regular Expressions yani Türkçe karşılığı
ile düzenli ifadeler konusuna değineceğiz.
Düzenli ifadeler, kısaca bir metin üzerinde çeşitli işlemler yapmaya
yarayan yardımcı bir araç olarak açıklanabilir.
Bu konuyu anlatmaya devam ederken içerisinde sıkça geçecek olan ?RegExp?
adlı (Regular Expressions ifadesinin kısaltılmış hali) ifadeyi
kullanacağım.
İlk başlarda regexp kullanırken oldukça zorlanabilirsiniz. Hatta bu
işlemler sizi o kadar sıkabilir ki bıkma noktasına gelebilirsiniz. Ama
bence vazgeçmemek en güzeli. Çünkü regexp ile işlem yapmak, alıştıktan
sonra hem çok zevkli hemde oldukça vakit kârı sağlayan bir iş. Açıkça
söylemek gerekirse, şu anda ben bile sıkça regexp ile işlemler yapmama
rağmen bir hayli zorlanıyorum.. ?Pattern yazmak bence başlı başına
bir sanat.?
Artık regexp hakkında azda olsa bir bilgi sahibiyiz.Şimdi regexp?nin
işleyiş tarzına gelelim..
RegExp ile fonksiyonlar yazarken bunun bazı nimetlerinden
yararlanacağız. Bunlar aşağıdaki şekildedir;
Özellikler
Pattern :
Verilen ifade içinde aranacak olan desen olarak özetlenebilir. Bu
desenler basit olabileceği gibi karmaşık ve uzun bir yapıya sahip
olabilirler.
Örn :
*.Pattern = ?[^a-zA-Z0-9]?
Global :
Aramanın nasıl yapılacağını belirler ve Boolean bir değer alır. Eğer
True olarak değer verilmişse, arama içindeki tüm uyumlara bakılır, False
olarak değer verilmişse sadece ilk uyum aranır.
Örn :
*.Global = True / False
IgnoreCase :
Arama yaparken ifadelerde büyük / küçük harf uyumuna bakar ve Boolean
bir değer alır. True değer verildiği taktirde aramada büyük / küçük harf
uyumuna bakılmaz, False değer verilmişse aramada büyük / küçük harf
uyumu aranır.
Örn :
*.IgnoreCase = True / False
Methodlar
Execute :
Yapılacak olan işlemin çalıştırılması için gerekli olan bir methoddur.
Text :
Bu methodu kontrol mekanizması olarak adlandırabiliriz.. Arama yapılacak
ifade içinde gerekli uyum varsa True yok ise false değer döndürür.
Replace :
Bu method ise vbscriptte kullandığımız ?replace? fonksiyonuna
benzer. Aranan ifade işleminde desen doğrulanıyorsa gerekli değiştirme
işlemi yapılır.
Not :
Methodlar hakkında detaylı bilgi aşağıda örnekli
anlatımlarda daha uzun olarak belirtileceklerdir.
Yukarıda bahsettiğimiz özellikler ve methodlar haricinde, girilen bir
karakter dizisinin, oluşturulan desene uyup uymadığını belirlemek için,
yine aynı isim alanı altında bulunan ?Match? adında nesneden
faydalanılır.
Bunun sonucunda ise az sonra aşğıda göreceğimiz bu ?Match?
nesnesine ait özellikler kullanılabilir.
Match Nesnesine Ait Özellikler
Count :
Verilen ifade içinde arama sonucunda uyumlu ne kadar değer bulunduğunu
ifade eder.
Örn :
Response.Write *.Count
Item :
Kullanımı SubMatches özelliğine benzer.
Örn :
Response.Write *.Item(x)
Matches Nesnesine Ait Özellikler
Bu özellik arama sonucunda bulunan değerleri ifade eder.
Value :
Verilen ifade içinde arama sonucunda dönen değer(ler) dir.
Örn :
Response.Write *.Value
Length :
Verilen ifade içinde arama sonucunda dönen değerin uzunluğunu verir.
Örn :
Response.Write *.Length
FirstIndex :
Verilen ifade içinde arama sonucunda dönen değerin baştan kaçıncı
karakterden başladığını verir
Örn :
Response.Write *.FirstIndex
SubMatches
Verilen ifade içinde arama sonucunda dönen değer dizi değişken olarak
gelmiş ise bunu kullanmamıza yarayan özelliktir.
Örn :
Response.Write *.SubMatches(0 / 1 / 2)
Evet bunlarıda burda kısaca açıkladıktan sonra sıra geldi pattern(desen)
nasıl yazılır, yazılırken nelere dikkat etmeliyiz gibi soruların
cevabına.
Pattern Elemanları
|
\ |
Kaçış karakteri olarak nitelendirilebilir. Regexp de pattern
yazarken bazı pattern değerleri önceden tanımlı olduğu için
bunları etkisizleştirmeye ve pattern içinde arama özelliği
olarak kullanmaya yarayan karakterdir. |
|
^ |
Ifade başlangıcı olduğunu belirtir. |
|
$ |
Ifade ya da satır sonu olduğunu belirtir. |
|
[] |
Karakter aralığı belirlemede kullanılır. Örn: [a-z] |
|
() |
Alt desen belirlemek için kullanılabilir. Örn: (\w) |
|
{} |
Alt ve üst limit belirleyerek sabit sayıda karakter girişini
sağlar. Örn: {n},{n,},{n,n} |
|
. |
Herhangi bir karakterin gelebileceği anlamına gelir |
|
? |
Önüne gelen karakter sayısından en fazla 1 en az 0 değerinde
olacağını belirtir. Örn: \d? |
|
* |
0 veya daha fazla karakter gelebilir anlamına gelmektedir. Örn :
\w* |
|
+ |
1 veya daha fazla karakter gelebilir anlamına gelmektedir. Örn :
\w+ |
|
| |
Birden fazla karakter grubunda bir veya bir kaçının olabileceği
anlamına gelmektedir. Örn : a|S|d |
Desenlerimizde kullababileceğimiz hazır olarak tanımlanmış karakter
setleri bulunmaktadır.. Bunlarıda şu şekilde sıralayabiliriz.
|
\w |
Sadece alfanümerik değerlerin gelebileceğini belirtir. Örn:
[a-zA-Z0-9_] |
|
\W |
Alfanümerik olmayan değerlerin gelebileceğini belirtir. Örn:
[^a-zA-Z0-9_] |
|
\s |
Boşluk karakterlerini ifade eder. Örn: [\f\n\r\t\v] |
|
\S |
Boşluk karakteri olmayan karakterleri ifade eder. Örn:
[^\f\n\r\t\v] |
|
\d |
0-9 arasında tek bir sayının olacağını ifade eder. Örn: [0-9] |
|
\D |
Rakam olmayan tek bir karakteri ifade eder. Örn: [^0-9] |
|
\b |
Bir kelimenin belirtilen dizi ile sonlanmasını ifade eder.
Örn: \w+\.asp\b |
|
\B |
Bir dizinin başında veya sonunda olmaması gereken karakterleri
ifade eder.
Örn : \w+\.asp\B |
|
\n |
Yeni satır karakterini ifade eder. |
|
\t |
Tab karakterini ifade eder. |
|
\r |
Satır başı karakterini ifade eder. |
|
\f |
Sayfa ilerletme karakterini ifade eder. |
|
\v |
Dikey tab karakterini ifade eder. |
|
\num |
Desen içinde yer alan ifade karşılıklarını kullanmamıza yarar.
Örn: <(b)>(.*)<\/\1> |
|
\xn |
Onaltılık(hexdecimal) sistemdeki bir karakteri ifade eder.
Örn: \x
40 ifadesi bana @ işaretini verir. |
Artık bunları da öğrendikten sonra yavaş yavaş desen kullanarak
birşeyler yapmaya başlayabiliriz.
Forumlarda sıkça karşılaştığım sorulardan örnekler vererek desenlerimizi
yazmaya çalışacağım..
Örnek 1 :
[url=http://www.maxiasp.com]Online ASP Eğitim
Merkezi[/url]
şeklindeki bir veriyi nasıl link yapacağımıza değinelim..
<%
Function LinkYap(GelenVeri)
Set objReg = New RegExp
With objReg
.Global = True
.IgnoreCase = True
.Pattern = "\[url=((http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}?/?[a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~]*)\](\s*[a-zA-Z0-9_]+((.|\n)*?)\s*)\[\/url\]"
End With
For Each Degerler In
objReg.Execute(GelenVeri)
GelenVeri
= Replace(GelenVeri,Degerler,"<a target='_blank' href='"&
Degerler.SubMatches(0) &"'>"& Trim(Degerler.SubMatches(2)) &"</a>",
1,-1,1)
Next
LinkYap = GelenVeri
End Function
strIcerik = ?[url=http://www.maxiasp.com]Online
ASP Eğitim Merkezi[/url] Bu Bir Deneme İşlemi <br>
[url=http://www.lyricsdatabase.gen.tr]LyricsDatabase[/url]?
Response.Write LinkYap(strIcerik)
%>
Bu işlemin Çıktısı;
Online ASP Eğitim Merkezi Bu Bir Deneme İşlemi
LyricsDatabase
Olacaktır.
Bu örneğimizde kullandığımız deseni kısaca
açıklayalım.
?[url=? paremetresinden sonra ?http ya da https ya da ftp? nin en az bir
tanesinin gelebileceğini bildiriyoruz. Daha sonra ?:? geleceğini ve
ardından ?//? olması gerekdiğini söylüyoruz. Ardından alfanumerik
karakterlerin ve 1 tane ?.? nın gelmesi gerektiğini sölüyoruz. Aynı
zamanda 2 veya 3 tane sayısal karakter içermeyen değerlerin
gelebileceğini ve alfanumerik olmayan karakterlerin olabileceğini
belirtiyoruz.
Bu anlattığım url kısmının olacağı yer idi.
Diğer tarafta ise 0 veya daha fazla beyaz
boşluk olabileceğini ve alfanumerik karakterler ile yeni satır
karakterlerinin gelebileceğini ifade ediyoruz..
Burası ise açıklama bölümünün olacağı yer.
Örnek 2 :
0 555 555 55 55 şeklindeki bir verinin doğruluğunun
kontrolünü yapalım.
<%
Function TelNoKontrol(GelenVeri)
Durum = True
Set objReg
= New RegExp
With
objReg
.Global =
True
.IgnoreCase = False
.Pattern = ?^0{1}\s\d{3}\s\d{3}\s\d{2}\s\d{2}$?
End With
Durum = objReg.Text(GelenVeri)
TelNoKontrol = Durum
End Function
Telefon = ?0
555 555 55 55?
If TelNoKontrol(Telefon) = True Then
Response.Write ?Telefon Numarası Doğru?
Else
Response.Write ?Telefon Numarası Yanlış?
End If
%>
Bu örneğin çıktısı ?Telefon Numarası
Doğru? olacaktır
Bu desenimizi şöyle açıklayabiliriz.
Başta 1 tane sıfır sayısının olması
gerektiğini ve ardından 1 tane beyaz boşluk onun artında 3 tane herhangi
bir sayı ve 1 tane beyazboşluk ardından 3 tane herhangi bir sayı ve 1
tane beyaz boşluk ardından 2 tane herhangi bir sayı ve 1 tane beyaz
boşluk ve ardından 2 tane herhangi bir sayı gelmesi gerektiğini
söylüyoruz.
Örnek 3 :
<html><br><head><br><title>Bu Bir Deneme
İşlemi</title><br><body>Deneme</body><br></head><br></html> şeklideki
veride bulunan ?<br>? tag?larını vbCrlf (enter) karakter seti ile
değiştirelim
<%
Function RegReplace(GelenVeri)
Set objReg = New RegExp
With objReg
.Global = True
.IgnoreCase = True
.Pattern = ?<br>?
End With
GelenVeri = objReg.Replace(GelenVeri,vbCrlf)
RegReplace = GelenVeri
End Function
strIcerik = ?<html><br><head><br><title>Bu
Bir Deneme İşlemi</title><br><body>Deneme</body><br></head><br></html>?
Response.Write RegReplace(strIcerik)
%>
Örneği çalıştırıp kaynak koduna
baktığınızda içeriğin,
<html>
<head>
<title>Bu Bir Deneme İşlemi</title>
<body>Deneme</body>
</head>
</html>
Şekilde olduğunu göreceksiniz.
Burda da gördüğünüz gibi verilen text
içinde ?<br>? taglarını arıyor..
Örnek 4 :
Bu son örneğimizi biraz geliştirelim ve
döviz kurlarını alalım..
<%
Session.Codepage = 1254
Response.CharSet =
"ISO-8859-9"
strUrl = "http://www.koc.net/finans/merkezdoviz.jsp"
Function MaxiParse(Url)
Set
XmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP.3.0")
XmlHTTP.Open "GET" ,
Url, False
XmlHTTP.Send
strContent =
XmlHTTP.ResponseText
MaxiParse = strContent
End Function
Function
GetirHadi(Text,Desen)
Set objReg
= New RegExp
With objReg
.Global
= True
.IgnoreCase = True
.Pattern
= Desen
End With
Set
objContent = objReg.Execute(Text)
For Each
Degerler In objContent
Deger = Deger &
Degerler.SubMatches(1) &","
Next
GetirHadi
= Deger
End Function
strIcerik =
MaxiParse(strUrl)
Isimler = GetirHadi(strIcerik,"<(td)\s+class\=\""v\"">(\s*[a-zA-Z0-9_]+((.|\n)*?)\s*)<\/\1>")
Fiyatlar = GetirHadi(strIcerik,"<(td)\s+align\=right\s+class\=\""ii\"">(.+)<\/\1>")
ubndIsimler =
Split(Left(Isimler,Len(Isimler)-1),",")
ubndFiyatlar =
Split(Left(Fiyatlar,Len(Fiyatlar)-1),",")
%>
<div align="center">
<table border="1"
width="300" id="table1" cellspacing="1" cellpadding="2"
style="border-collapse: collapse">
<tr>
<td width="40%"
bgcolor="#0066CC">
<p
align="center"><b><font face="Verdana" size="2" color="#FFFFFF">Döviz
Adı</font></b></td>
<td width="30%"
bgcolor="#0066CC">
<p
align="center"><b><font face="Verdana" size="2"
color="#FFFFFF">Alış</font></b></td>
<td width="30%"
bgcolor="#0066CC">
<p
align="center"><b><font face="Verdana" size="2"
color="#FFFFFF">Satış</font></b></td>
</tr>
<%
i = 0
For x = 0 To
uBound(ubndIsimler)
Response.Write "<tr><td width=""150"" bgcolor=""#FFFFCC""><p
align=""right""><b><font face=""Verdana"" size=""1"">"& ubndIsimler(x)
&"</font></b></td>"&_
"<td
width=""75"" bgcolor=""#F1F1F1""><p align=""center""><font
face=""Verdana"" size=""1"">"& ubndFiyatlar(x+i) &"</font></td>"&_
"<td
width=""75"" bgcolor=""#F1F1F1""><p align=""center""><font
face=""Verdana"" size=""1"">"& ubndFiyatlar(x+i+1) &"</font></td></tr>"&
vbCrlf
i = i +
1
Next
%>
</table>
</div>
<% Response.Write "<p
align=""center""><font face=""Verdana"" size=""1"">Coded By PsyChaos -
semih[at]maxiasp[dot]com</font>" %>
Bu örneğin çıktısı aşağıdaki şekildeki
gibi olacaktır.
|
Döviz Adı |
Alış |
Satış |
|
Avusturalya Doları |
1.035.082 |
1.041.854 |
|
Kanada Doları |
1.089.532 |
1.094.457 |
|
Danimarka Kronu |
239.050 |
240.227 |
|
Euro |
1.777.605 |
1.786.179 |
|
İngiliz Sterlini |
2.660.090 |
2.673.995 |
|
Japon Yeni |
13.225 |
13.313 |
|
Kuveyt Dinarı |
4.837.947 |
4.901.669 |
|
Norveç Kronu |
210.518 |
211.938 |
|
Suudi Riyali |
384.601 |
385.295 |
|
İsveç Kronu |
192.595 |
194.599 |
|
İsvicre Frangı |
1.168.428 |
1.175.954 |
|
ABD Doları |
1.438.076 |
1.445.012 |
Şimdi desenimizde ne gibi özellikler
kullandık onu anlatalım..
Olaya birinci desenimizi anlatarak
başlayalım.
İlk başta ifade karşılıklarını kullanarak (\num) ?td? alanının
kopyasını aldım.Daha sonra 1 veya daha fazla beyaz bışluk gelebileceğini
söyledim..Ardındanda alacağım yerde kullanılan bir takım karakter
kümüsinin geleceğini belirttim..Şimdi anlatacağım yer buranın can alıcı
noktası..Burda 0 veya daha fazla beyaz boşluk geleceğini belirterek yine
birden fazla alfanumerik değerlerin gelebileceğini ve ardından herhangi
bir karakter veya yeni satır karakterinin 0 veya daha fazla geleceğini
belirttim.. Diğer yanda ise aldığımız ?td? ifadesini yapıştırdım..
Bu desen ile döviz adlarını parse ettim..
İkinci desenimizde ise birincide
yaptığımız gibi gerekli alanın kopyasını çıkarıp ardından kesin olarak
gelebilecek karakterler kümesini yazdım..Ardından 1 veya daha fazla
karakter gelebileceğini belirttim.. Diğer yanda ise aldığımız ?td?
ifadesini yapıştırdım..
Bu desen ile de alış ve satış kurlarını
parse ettim..
Örneklerimiz ve anlatacaklarım bu kadar.
Konunun ilk başında da dediğim gibi. Başta desenler yazarken oldukça
zorlanabilirsiniz. Fakat pes etmenizide istemem..
Hazır desenlerin bulunduğu
http://www.regexplib.com adresine bakmanızı şiddetle tavsiye
ederim.. Ayrıca yazdığınız desenlerin çalışıp çalışmadığını ya da doğru
çalışıp çalışmadığını kontrol etmeniz için ise
http://www.radsoftware.com.au/web/Products/RegexDesigner/ adresinden
?Regular Expression Designer? adlı programı çekip kullanmanızı
öneriyorum..
Herkese iyi çalışmalar dilerim.
Yazar :
Semih Turna
E-Mail : semih[at]maxiasp[dot].com
|