7 Mart 2020 Cumartesi

Excel VBA'da Regular Expressions(Düzenli İfadeler) kullanımı

Regular Expressions(Düzenli ifadeler) nedir?

Kısaca RegEx veya RegExp olarak kullanılan düzenli ifadeler günümüz modern programlama dillerinin birçoğunda bulunmaktadır.
Regex, ele alınan metindeki karakterler dizisinin kısa yoldan ve esnek bir biçimde bulunmasını ve gerekirse değiştirmesini sağlar.

RegEx hakkında ayrıltılı açıklama için şu sayfalara da bakabilirsiniz:
Perl Regular Expressionlar 1

List_of_Regular_Expressions
Wikipedi Düzenli ifade

İngilizce kaynaklar:
Regexr.com
Regular-expressions.info
Regex101.com
Rexegg.com
Regexone.com

Excel VBA'da RegEx kullanımı

Normalde Excel VBA'da RegEx ile ilgili bir özellik yoktur. Ancak Microsoft VBScript Regular Expressions referansı ile bu sağlanabilmektedir.

Excel VBA'ya bu referansı eklemek için iki yol var:

1. yol:

Excel VBA Editöründe(ALT+F11) iken menüden Tools / References ... tıklanır. Açılan pencerede listeden Microsoft VBScript Regular Expressions seçilip OK tıklanır.
Sub Test()
 ' Tools / Reference ile
 ' Microsoft VBScript Regular Expressions
 ' ekleyin
 Dim RegEx As RegExp
 Set RegEx = New RegExp

2. yol:

VBA kodlarıyla RegEx nesnesi oluşturmak:
Sub Test()
 Dim RegEx As Object
 Set RegEx = CreateObject("VBScript.RegExp")

Kodlar taşınacaksa 2. yol daha kullanışlı olacaktır. Böylece kullanıcı menüden referans ekleme işlemiyle uğraşmayacaktır.

Bu yollardan birini uyguladıktan sonra VBA içinde RegEx kullanılabilir hale gelecektir.

RegEx Nesnesinin Özellikleri:


Pattern: Eşleştirilmek istenen kalıp(desen).
Global: True: Olası tüm eşleşmeleri bulur. False: Yalnızca ilk bulunan desenle eşleşir.
IgnoreCase: Büyük/küçük harf duyarlılığı. True: Duyarsız. False: Duyarlı
MultiLine: Birden çok satır varsa diğer satırlara bakılacak mı?. True: Evet. False: Hayır

RegEx Nesnesinin Fonksiyonları

Execute (bulunacak metin) : desenin tüm eşleşmelerini arama dizesine göre döndürür.
Replace (bulunacak metin, değiştirilecek metin) : arama metnindeki desenin oluşumlarını değiştirme metni ile değiştirir.
Test (metin) : desen, verilen metinle eşleşiyorsa True sonucunu döndürür.

Örnekle RegEx'i kullanalım.

Desen eşleşmesini test etme:

Sub RegExTest()
 Dim RegEx As Object, metin As String
 Set RegEx = CreateObject("VBScript.RegExp")
  
 RegEx.Pattern = "[0-9]+"
  
 metin = "Merhaba Dünya!"
 Debug.Print RegEx.test(metin) 'False
  
 metin = "Merhaba! Tarih: Mart 2020"
 Debug.Print RegEx.test(metin) 'True
End Sub
Pattern olarak [0-9]+ kullanıldı. Bu verilen metinde 1 ya da daha fazla rakam arar. Örnekte 2. metin içinde 2020 sayısı rakam 0-9 arası rakam içerdiği için verilen desen(pattern) ile eşleşti bu yüzden True sonucu alındı. [0-9]+ yerine \d+ kullanılabilir

Metinde desenle eşleşeni değiştirme:

Sub RegExReplace1()
 Dim regex As RegExp
 Set regex = New RegExp

 regex.Pattern = "[0-9]+"
 'Alternatif:
 'regex.Pattern = "\d+"

 metin = "Benim telefon numaram 8221615. Arkadaşımınki 8336587"

 regex.Global = False
 Debug.Print regex.Replace(metin, "4009123")
 'Benim telefon numaram 4009123. Arkadaşımınki 8336587

 regex.Global = True
 Debug.Print regex.Replace(metin, "4009123")
 'Benim telefon numaram 4009123. Arkadaşımınki 4009123
End Sub
Global özelliği True olduğunda desenle eşleşen tüm metinlerin, False olduğunda eşleşen ilk metnin değiştiğine dikkat ediniz.
Sub RegExReplace2()
 Dim regex As RegExp
 Set regex = New RegExp

 regex.Pattern = "\d+-\d+"
 metin = "TC MEB 2018-2019 Öğretim yılı"

 Debug.Print regex.Replace(metin, "2019-2020")
 'TC MEB 2019-2020 Öğretim yılı
End Sub
\d : rakam, + : bir ya da daha fazla.
\d+ : bir yada daha fazla rakam

Metindeki desen eşleştirmeleri

Örnek 1:
Sub RegExExecute1()
 Dim regex As RegExp
 Set regex = New RegExp

 regex.Global = True
 metin = "sen seni bil, sen seni, sen seni bilmezsen, patlatırlar enseni"

 regex.Pattern = "sen"
 Set eslesmeler = regex.Execute(metin)
 sensayisi = eslesmeler.Count
 Debug.Print "cümlede içinde sen olan " & sensayisi & " kelime var"
 'cümlede içinde sen olan 8 kelime var

 regex.Pattern = "\bsen" 'sen ile başlayan
 Set eslesmeler = regex.Execute(metin)
 sensayisi = eslesmeler.Count
 Debug.Print "cümlede sen ile başlayan " & sensayisi & " kelime var"
 'cümlede sen ile başlayan 6 kelime var
End Sub
Örnek 2:
Sub RegExExecute2()
 Dim regex As RegExp
 Set regex = New RegExp

 htmkod = "<html><head><title>RegEx hakkında</title></head></html>"
 regex.Pattern = "<title>(.*)</title>"

 If regex.Test(htmkod) Then
  h = regex.Execute(htmkod)(0)
  Debug.Print regex.Replace(h, "$1")
  'RegEx hakkında
 End If
End Sub
Örnek 3:
Sub RegExExecute2()
 Dim regex As RegExp
 Set regex = New RegExp

 metin = "Telefon no: 02138446832 Türkiye"
 regex.Pattern = "0([\d]{3})([\d]{7})"

 If regex.Test(metin) Then
  h = regex.Execute(metin)(0)
  Debug.Print "Alan kodu: " & regex.Replace(h, "$1")
  'Alan kodu: 213
  Debug.Print "Telefon numarası: " & regex.Replace(h, "$2")
  'Telefon numarası: 8446832
  Debug.Print "Tlf: " & regex.Replace(h, "0($1)$2")
  'Tlf: 0(213)8446832
 End If
End Sub
Örnek 4:
Sub RegExExecute4()
 Dim regex As Object, str As String
 Set regex = CreateObject("VBScript.RegExp")
  
 With regex
  .Pattern = "NO:\d+"
  .Global = True
 End With
  
 str = "NO:123-444-NO:2454-NO:888-987"
  
 Set matches = regex.Execute(str)
  
 For Each Match In matches
  Debug.Print Match.Value
 Next
 'NO:123
 'NO:2454
 'NO:888
End Sub
Örnek 5:
Sub RegExExecute5()
Dim regex As RegExp
Set regex = New RegExp
With regex
 .Pattern = "XYZ-(\d+)"
 .Global = True
End With
    
metin = "321-XYZ-000-XYZ-643-XYZ-888-XYZ+777"
 
Set eslesmeler = regex.Execute(metin)

For Each eslesme In eslesmeler
 Debug.Print eslesme.Value
 If eslesme.SubMatches.Count > 0 Then
  For Each alteslesme In eslesme.SubMatches
   Debug.Print alteslesme
  Next
 End If
Next
'XYZ-000
'000
'XYZ-643
'643
'XYZ-888
'888
End Sub

Hiç yorum yok:

Yorum Gönder