Etiketler

Youtube Kanalıma Abone Olunuz

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'de Regular Expressionlar 1
Perl'de Regular Expressionlar 2
Perl'de Regular Expressionlar 3

List_of_Regular_Expressions

İngilizce kaynaklar:
Wikipedi Düzenli ifade
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