Etiketler

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önderme