Regularni izrazi u VB6
Nivo znanja:
Beginner - Intermediate
U ovom tutorijalu ću objasniti kako da koristite regularne izraze (regular expressions) u VB6.
Ukoliko ne znate šta su to regularni izrazi možete pogledati na wikipediji
Regular expression; ukratko rečeno regularni izrazi nam omogućavaju lako i brzo manipulisanje tekstom, bilo da zahtevamo da string bude u odredjenoj formi (recimo da proveravamo validnost email adrese), ili da želimo da "iscupamo" odredjene delove teksta, ili da ih zamenimo sa nečim drugim, regularni izrazi su najbolji način (i najbrži) da to učinimo.
Visual Basic 6 nažalost nema ugradjenu podršku za regularne izraze (za razliku od VB.NET-a) ali ništa nas ne sprečava da koristimo VBScript Regular Expressions biblioteku. Ova biblioteka je deo Internet Explorera i postoji u dve verzije 1.0 (korišćena u IE4) i 5.5 (koristi se u IE 5.5 i nadalje), i kako je Internet Explorer 5.5 uključen u instalaciju Windows-a 98 sasvim je sigurno koristiti ovu biblioteku jer nema instalacije Windowsa koji ne sadrži pomenuti dll (čak i Windows XP koji dolazi bez IE-a ima tu biblioteku).
Dakle, da pređemo na stvar. Pokrenite VB6 i izaberite Standard EXE projekat, u meniju Project izaberite References i u dobijenoj listi pronađite i čekirajte Microsoft VBScript Regular Expressions 5.5, pritisnite OK i to je to, sada imate podršku za regularne izraze u VB6!
Sledi ukratko objašnjenje objekata koji se nalaze u VBScript Regular Expressions biblioteci:
Code:
RegExp Class:
+=============================================================================+
| Properties |
+=============================================================================+
| Property Pattern As String |
| - najvažnije svojstvo RegExp objekta, ovde podešavamo regularni izraz koji|
| će biti korišćen u Execute, Replace i Test procedurama |
+-----------------------------------------------------------------------------+
| Property Global As Boolean (podrazumevana vrednost je False) |
| - ukoliko je ovo svojstvo True regularni izraz će biti izvršen na celom |
| sourceString-u, tj biće pronadjeni svi delovi stringa koji odgovaraju |
| regularnom izrazu, ukoliko je ovo svojstvo False onda će RegExp objekat |
| stati na prvom "pogotku" (Match) |
+-----------------------------------------------------------------------------+
| Property Multiline As Boolean (podrazumevana vrednost je False) |
| - slično kao kod Global svojstva, ukoliko je True regularni izraz će biti |
| izvršen na svim linijama teksta, a ukoliko je False onda samo na jednoj |
+-----------------------------------------------------------------------------+
| Property IgnoreCase As Boolean (podrazumevana vrednost je False) |
| - ukoliko je ovo svojstvo True pretraga će biti case-insensitive, tj mala |
| i velika slova su ista, a ako je False onda će pretraga razlikovati mala|
| slova od velikih. |
+=============================================================================+
+=============================================================================+
| Methods |
+=============================================================================+
| Function Execute(sourceString As String) As MatchCollection |
| - izvršava regularni izraz (podešen u Pattern svojstvu) na sourceString |
| tekstu i vraća MatchCollection objekat |
+-----------------------------------------------------------------------------+
| Function Replace(sourceString As String, replaceString As String) As String |
| - isvršava regularni izraz (podešen u Pattern svojstvu) na sourceString |
| tekstu i menja sve delove teksta koji odgovaraju reguloarnom izrazu sa |
| replaceString tekstom (koji može da sadrži tzv backreferences) |
+-----------------------------------------------------------------------------+
| Function Test(sourceString As String) As Boolean |
| - izvršava regularni izraz (podešen u Pattern svojstvu) na sourceString |
| tekstu i vraća True ukoliko sourceString odgovara izrazu ili False ako |
| ne odgovara |
+=============================================================================+
MatchCollection Class:
+=============================================================================+
| Properties |
+=============================================================================+
| Default Property Item(Index As Long) As Match (Read Only) |
| - vraća Match objekat iz kolekcije |
+-----------------------------------------------------------------------------+
| Property Count As Long (Read Only) |
| - vraća broj Match objekata u kolekciji |
+=============================================================================+
Match Class:
+=============================================================================+
| Properties |
+=============================================================================+
| Default Property Value As String (Read Only) |
| - vraća tekst koji odgovara regularnom izrazu |
+-----------------------------------------------------------------------------+
| Property FristIndex As Long (Read Only) |
| - vraća poziciju u stringu na kojoj je ovaj Match objekat definisan, ovo |
| svojstvo je 0-based, tj prvi karakter u stringu je na poziciji 0, za |
| razliku od ugradjenih VB6 funkcija u kojima je prvi karakter na poziciji |
| 1 |
+-----------------------------------------------------------------------------+
| Propety Length As Long (Read Only) |
| - vraća dužinu prodnadjenog teksta |
+-----------------------------------------------------------------------------+
| Property SubMatches As SubMatches (Read Only) |
| - vraća kolekciju stringova koji predstavljaju tzv podpogotke, tj ako je |
| izraz sadržao podizraze (subexpressions) koji se definišu pomoću zagrada |
| onda SubMatches sadrži po jedan string za svaki podizraz |
+=============================================================================+
SubMatches Class:
+=============================================================================+
| Properties |
+=============================================================================+
| Default Property Item(Index As Long) As String (Read Only) |
| - vraća string iz kolekcije |
+-----------------------------------------------------------------------------+
| Property Count As Long (Read Only) |
| - vraća broj stringova u kolekciji |
+=============================================================================+
Sada ćemo napraviti aplikaciju pomoću koje možemo da testiramo regularne izraze.
Kao dodatak tutorijalu biće objašnjena i upotreba RichTextBox kontrole, nju ćemo koristiti da prikažemo rezultate u lepo formatiranom obliku (sa raznim stilovima fonta i bojama)
Pokrenite VB6 i izaberite Standard EXE projekat, dodajte podršku sa regularne izraze (ovo je objašnjeno gore) i dodajte RichTextBox kontrolu (ovo ćete uraditi tako što u Project meniju izaberete Components, pronadjite i čekirajte Microsoft Rich TextBox Control 6.0 i pritisnike OK).
Na formu dodajte sledeće:
- TextBox (Name = txtExpression, Text = (prazno), Font = Courier New 9)
- TextBox (Name = txtSourceString, Text = (prazno))
- TextBox (Name = txtReplaceWith, Text = (prazno))
- CheckBox (Name = chbGlobal, Caption = Global)
- CheckBox (Name = chbMultiline, Caption = Multiline)
- CheckBox (Name = chbIgnoreCase, Caption = IgnoreCas)
- CommandButton (Name = cmdExecute, Caption = &Execute)
- CommandButton (Name = cmdReplace, Caption = &Replace)
- CommandButton (Name = cmdTest, Caption = &Test)
- CommandButton (Name = cmdClear, Caption = &Clear)
- RichTextBox (Name = rtbResults, ScrollBars = 2 - rtfVertical, Text = (prazno))
kontrole možete pozicionirati kako hoćete, ja sam sve složio ovako (dodao sam dva frejma i par labela, i TextBox-ovima sam podesio Alignment na 1 - Right Justify):
kada ste složili kontrole kako hoćete možemo preći na kod, evo prvo koda za cmdExecute_Click
Code:
' Execute metoda
Private Sub cmdExecute_Click()
On Error GoTo hell
Dim oRegExp As RegExp
Dim oMatches As MatchCollection
Dim oMatch As Match
Dim oSubMatches As SubMatches
Dim lIndex As Long
' prvo da proverimo da li su uneti potrebni podaci
If LenB(txtExpression) = 0 Then
MsgBox "You must enter regular expression.", vbExclamation, "Error"
txtExpression.SetFocus
Exit Sub
End If
If LenB(txtSourceString) = 0 Then
MsgBox "You must enter source string.", vbExclamation, "Error"
txtSourceString.SetFocus
Exit Sub
End If
' kreiramo novi RegExp objekat
Set oRegExp = New RegExp
' podesavamo regularni izraz
oRegExp.Pattern = txtExpression.Text
' podesavamo opcije
oRegExp.Global = chbGlobal.Value
oRegExp.MultiLine = chbMultiline.Value
oRegExp.IgnoreCase = chbIgnoreCase.Value
' izrsavamo regularni izraz
Set oMatches = oRegExp.Execute(txtSourceString.Text)
' upisujemo regularni izraz u rich text box
AppendRichText vbNewLine & "Expression: "
AppendRichTextLn txtExpression.Text & vbNewLine, vbBlue, Monospace Or Italic
' upisujemo source string
AppendRichText "Source string: "
AppendRichTextLn txtSourceString.Text & vbNewLine, RGB(64, 0, 0), Bold
If oMatches.Count = 0 Then
AppendRichTextLn " - No matches found."
Else
AppendRichText " Found "
AppendRichText oMatches.Count, , Bold
AppendRichTextLn " match(es):"
For Each oMatch In oMatches
With oMatch
' Value
AppendRichTextLn " " & .Value, RGB(0, 128, 0), Monospace Or Italic
' FirstIndex
AppendRichText " " & " FirstIndex: "
AppendRichTextLn .FirstIndex, RGB(128, 0, 0), Bold Or Monospace
' Length
AppendRichText " " & " Length: "
AppendRichTextLn .Length, RGB(128, 0, 0), Bold Or Monospace
'SubMatches
Set oSubMatches = .SubMatches
AppendRichText " " & " SubMatches: "
AppendRichTextLn oSubMatches.Count, RGB(128, 0, 0), Bold Or Monospace
For lIndex = 0 To oSubMatches.Count - 1
AppendRichText " " & lIndex, RGB(128, 0, 0), Bold Or Monospace
AppendRichTextLn " " & oSubMatches(lIndex), RGB(0, 128, 0), Monospace
Next
End With
AppendRichTextLn " " & String(80, "-") ' separator
Next
AppendRichTextLn " " & String(80, "-") ' separator
End If
Exit Sub
hell:
MsgBox Err.Description, vbCritical, "Error [" & Err.Source & ": " & Err.Number & "]"
Err.Clear
End Sub
kada proverimo da su uneti potrebni podaci (regularni izraz i source string) onda kreiramo novi RegExp objekat i izvršavamo regularni izraz:
Code:
' kreiramo novi RegExp objekat
Set oRegExp = New RegExp
' podesavamo regularni izraz
oRegExp.Pattern = txtExpression.Text
' podesavamo opcije
oRegExp.Global = chbGlobal.Value
oRegExp.MultiLine = chbMultiline.Value
oRegExp.IgnoreCase = chbIgnoreCase.Value
' izrsavamo regularni izraz
Set oMatches = oRegExp.Execute(txtSourceString.Text)
sada oMatches sadrži 0 ili više Match objekata.
Ukoliko je broj Match objekata 0 štampamo " - No matches found." a ukoliko je taj broj veći od nula onda za svaki oMatch objekat u oMatches kolekciji štampamo podatke (svojstva Match objekta).
Za štampanje smo koristili AppendRichText i AppendRichTextLn funkcije, sledi njihov kod:
Code:
' dodaje text u richtextbox i formatira ga
Private Sub AppendRichText(sText As String, _
Optional color As Long = vbBlack, _
Optional style As RichStyles = Normal)
Dim iStart As Long
With rtbResults
iStart = Len(.Text) + 1
.SelStart = iStart
.SelLength = Len(sText)
.SelColor = color
.SelBold = style And Bold
.SelItalic = style And Italic
.SelUnderline = style And Underline
.SelFontName = IIf(style And Monospace, "Courier New", "Arial")
.SelText = sText
End With
End Sub
'
Private Sub AppendRichTextLn(sText As String, _
Optional color As Long = vbBlack, _
Optional style As RichStyles = Normal)
AppendRichText sText & vbNewLine, color, style
End Sub
i još na vrh forme dodajte deklaraciju za RichStyle:
Code:
Enum RichStyles
Normal = 0
Italic = 1
Bold = 2
Underline = 4
Monospace = 8
End Enum
AppendRichText dodajte text u richtextbox i formatira ga na sledeći način:
prvo zapamtimo dužinu teksta koji je trenutno u rtbResults i dodamo 1 (ova vrednost će da bude početna pozicija string koji dodajemo - SelStart)
zatim podesimo dužinu teksta koji unosimo (SelLength), boju (SelColor), stil (SelBold, SelItalic, SelUnderline), font (SelFontName)
i na kraju dodamo tekst (SelText) koji će biti formatiran
AppendRichTextLn radi to isto (poziva AppendRichText) samo što na kraj stringa dodaje vbNewLine (prelaz u novi red)
Sada možete pokrenuti program da isprobamo da li Execute metoda radi. Unesite neki regularni izraz i source string i pritisnite Execute. Evo mog rezultata:
sada sledi kod za cmdReplace_Click:
Code:
' Replace metoda
Private Sub cmdReplace_Click()
On Error GoTo hell
Dim oRegExp As RegExp
Dim sResult As String
' prvo da proverimo da li su uneti potrebni podaci
If LenB(txtExpression) = 0 Then
MsgBox "You must enter regular expression.", vbExclamation, "Error"
txtExpression.SetFocus
Exit Sub
End If
If LenB(txtSourceString) = 0 Then
MsgBox "You must enter source string.", vbExclamation, "Error"
txtSourceString.SetFocus
Exit Sub
End If
' kreiramo novi RegExp objekat
Set oRegExp = New RegExp
' podesavamo regularni izraz
oRegExp.Pattern = txtExpression.Text
' podesavamo opcije
oRegExp.Global = chbGlobal.Value
oRegExp.MultiLine = chbMultiline.Value
oRegExp.IgnoreCase = chbIgnoreCase.Value
' izvrsavamo regexp replace
sResult = oRegExp.Replace(txtSourceString.Text, txtReplaceWith.Text)
' upisujemo regularni izraz u rich text box
AppendRichText vbNewLine & "Expression: "
AppendRichTextLn txtExpression.Text & vbNewLine, vbBlue, Monospace Or Italic
' upisujemo source string
AppendRichText "Source string: "
AppendRichTextLn txtSourceString.Text & vbNewLine, RGB(64, 0, 0), Bold
' upisujemo replace with string
AppendRichText "Replace with: "
AppendRichTextLn txtReplaceWith.Text & vbNewLine, RGB(0, 128, 0), Bold
' upisujemo rezultat
AppendRichText "Result: "
AppendRichTextLn sResult & vbNewLine, RGB(128, 0, 0), Italic Or Monospace
AppendRichTextLn " " & String(80, "-") ' separator
Exit Sub
hell:
MsgBox Err.Description, vbCritical, "Error [" & Err.Source & ": " & Err.Number & "]"
Err.Clear
End Sub
Priča je ista kao kod Execute samo što sad izvršavamo Replace metodu RegExp objekta i prosledjujemo joj dva parametra, source string i string kojim će svaki Match biti zamenjen.
U replace with stringu je moguće koristiti tzv backreferences, tj ako se u replace with nalazi $1 to će biti zamenjeno sa prvim podizrazom u regularnom izrazu (tj ono što se nalazi u prvoj zagradi), $2 odgovara drugom podizrazu itd.
Evo mog rezultata:
od RegExp metoda nam je ostala još Test metoda, evo koda za cmdTest_Click:
Code:
' Test metoda
Private Sub cmdTest_Click()
On Error GoTo hell
Dim oRegExp As RegExp
Dim bResult As Boolean
' prvo da proverimo da li su uneti potrebni podaci
If LenB(txtExpression) = 0 Then
MsgBox "You must enter regular expression.", vbExclamation, "Error"
txtExpression.SetFocus
Exit Sub
End If
If LenB(txtSourceString) = 0 Then
MsgBox "You must enter source string.", vbExclamation, "Error"
txtSourceString.SetFocus
Exit Sub
End If
' kreiramo novi RegExp objekat
Set oRegExp = New RegExp
' podesavamo regularni izraz
oRegExp.Pattern = txtExpression.Text
' podesavamo opcije
oRegExp.Global = chbGlobal.Value
oRegExp.MultiLine = chbMultiline.Value
oRegExp.IgnoreCase = chbIgnoreCase.Value
' izvrsavamo test
bResult = oRegExp.Test(txtSourceString.Text)
' upisujemo regularni izraz u rich text box
AppendRichText vbNewLine & "Expression: "
AppendRichTextLn txtExpression.Text & vbNewLine, vbBlue, Monospace Or Italic
' upisujemo source string
AppendRichText "Source string: "
AppendRichTextLn txtSourceString.Text & vbNewLine, RGB(64, 0, 0), Bold
' upisujemo rezultat
AppendRichText "Test: "
If bResult Then
AppendRichTextLn "Success" & vbNewLine, RGB(0, 128, 0), Monospace Or Italic
Else
AppendRichTextLn "Failed" & vbNewLine, RGB(255, 0, 0), Monospace Or Italic Or Bold
End If
AppendRichTextLn " " & String(80, "-") ' separator
Exit Sub
hell:
MsgBox Err.Description, vbCritical, "Error [" & Err.Source & ": " & Err.Number & "]"
Err.Clear
End Sub
pokrenite program i isprobajte test metodu, prvo u source string unesite string za koji znate da će odgovara regularnom izrazu a onda string koji ne odgovara izrau (da bi dobili i Success i Failed), evo mog rezultata:
i ostao nam je još kod za cmdClear_Click - jednostavno brišemo sadržaj rtbResult:
Code:
Private Sub cmdClear_Click()
rtbResults.Text = vbNullString
End Sub
i to je to. Uz poruku sam okačio ceo projekat, a u zipu se nalazi i exe verzija programa.
[Ovu poruku je menjao Aleksandar Ružičić dana 15.02.2008. u 13:06 GMT+1]