Introduction
This is a very small program that demonstrates that useful programs do not need to be large. While toying with the idea of automated download and build of source included in Wikibooks I needed to test some Regular Expressions. I searched the Web for ready made tools but found nothing that really fitted what I wanted to do. Eric Gunnerson's C# tool is very good but relies on the .NET libraries which seems an unnecessarily large overhead for such a small program. So I built my own in about fifteen minutes. Here it is, it has the bare minimum of error checking, the controls are not neatly arranged and the form is not resizeable, or rather it is but the controls don't. It has a lot of limitations and definitely needs improvement, see Exercises.
frmRegExpTester.frm
This form is the only module in the program. All the difficult work is done by the VBScript Regular Expression Library. See Regular Expressions.
The control layout on the form is just what first came to mind. It definitely needs improvement in several areas: resizeability, tab order, etc.
There is a control for each of the properties and methods of the RegExp class so you can exercise all of the capabilities of it. each of the controls reacts to the Changed Click events by setting properties as appropriate and calling both the Test and Execute methods.
VERSION 5.00
Begin VB.Form frmRegExpTester
Caption = "Form1"
ClientHeight = 11700
ClientLeft = 60
ClientTop = 360
ClientWidth = 11010
BeginProperty Font
Name = "System"
Size = 9.75
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
LinkTopic = "Form1"
ScaleHeight = 11700
ScaleWidth = 11010
StartUpPosition = 3 'Windows Default
Begin VB.TextBox txtTestresult
BeginProperty Font
Name = "Fixedsys"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 495
Left = 1320
TabIndex = 10
Text = "Text1"
Top = 2880
Width = 4095
End
Begin VB.TextBox txtExecuteresult
BeginProperty Font
Name = "Fixedsys"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 9135
Left = 6840
MultiLine = -1 'True
TabIndex = 9
Text = "frmRegExpTester.frx":0000
Top = 2520
Width = 4095
End
Begin VB.TextBox txtReplace
BeginProperty Font
Name = "Fixedsys"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 615
Left = 960
MultiLine = -1 'True
TabIndex = 5
Text = "frmRegExpTester.frx":0006
Top = 1440
Width = 8295
End
Begin VB.CheckBox chkMultiLine
Caption = "Multiline"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 495
Left = 3360
TabIndex = 4
Top = 840
Value = 1 'Checked
Width = 1575
End
Begin VB.CheckBox chkIgnoreCase
Caption = "Ignore Case"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 375
Left = 1800
TabIndex = 3
Top = 960
Value = 1 'Checked
Width = 1575
End
Begin VB.CheckBox chkGlobal
Caption = "Global"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 375
Left = 240
TabIndex = 2
Top = 960
Value = 1 'Checked
Width = 1455
End
Begin VB.TextBox txtPattern
BeginProperty Font
Name = "Fixedsys"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 615
Left = 840
MultiLine = -1 'True
TabIndex = 1
Text = "frmRegExpTester.frx":000C
Top = 120
Width = 8535
End
Begin VB.TextBox txtSource
BeginProperty Font
Name = "Fixedsys"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 6735
Left = 0
MultiLine = -1 'True
TabIndex = 0
Text = "frmRegExpTester.frx":0022
Top = 4920
Width = 5655
End
Begin VB.Label Label3
Caption = "Test status"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 0
TabIndex = 11
Top = 3000
Width = 1215
End
Begin VB.Label Label2
Caption = "Execute status"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 255
Left = 5520
TabIndex = 8
Top = 2640
Width = 1215
End
Begin VB.Label Label1
Caption = "Replacement"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 375
Index = 1
Left = 0
TabIndex = 7
Top = 1560
Width = 735
End
Begin VB.Label Label1
Caption = "Pattern"
BeginProperty Font
Name = "MS Sans Serif"
Size = 8.25
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 375
Index = 0
Left = 0
TabIndex = 6
Top = 240
Width = 735
End
End
Attribute VB_Name = "frmRegExpTester"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
The RegExp instance is available to all the code in this module although this is not strictly necessary because we could create a new one each time.
Private moRe As RegExp
Each of the Boolean properties is represented by a CheckBox control. The click event for each one simply sets the appropriate property value and calls the Execute method via the xExecute local subroutine.
Private Sub chkGlobal_Click() moRe.Global = chkGlobal = vbChecked xExecute End Sub Private Sub chkIgnoreCase_Click() moRe.IgnoreCase = chkIgnoreCase = vbChecked xExecute End Sub Private Sub chkMultiLine_Click() moRe.MultiLine = chkMultiLine = vbChecked xExecute End Sub
When the form is created the Initialize event handler is called. This creates the RegExp instance and sets the properties to correspond to the values of the controls.
Private Sub Form_Initialize()
Set moRe = New RegExp
With moRe
.Global = chkGlobal = vbChecked
.IgnoreCase = chkIgnoreCase = vbChecked
.MultiLine = chkMultiLine = vbChecked
.Pattern = txtPattern
End With
End Sub
When the user changes either the regular expression or the source text the output is updated by calling xExecute
Private Sub txtPattern_Change() xExecute End Sub Private Sub txtSource_Change() xExecute End Sub
This is the heart of the program. All it does is to call the Execute method and then construct a string to represent the result. If the pattern is invalid then the Execute method will raise an error. this is trapped and the error description used instead of the result. The result object is declared as Object because the return type can be either Match' or MatchCollection depending on whether there is only one match or more than one. The results are shown in the txtExecuteResult and txtTestresult text boxes.
Private Sub xExecute()
moRe.Pattern = txtPattern
Dim o As Object
On Error Resume Next
Set o = moRe.Execute(txtSource)
If Err Then
txtExecuteresult = Err.Number & ", " & Err.Description
Else
On Error GoTo 0
If TypeOf o Is Match Then
txtExecuteresult = xMatchToString(o)
ElseIf TypeOf o Is MatchCollection Then
txtExecuteresult = xMatchCollectionToString(o)
End If
End If
On Error GoTo 0
On Error Resume Next
txtTestresult = moRe.Test(txtSource)
If Err Then
txtTestresult = Err.Number & ", " & Err.Description
End If
On Error GoTo 0
End Sub
The whole purpose of the program is to show the user what the result of matching the regular expression to a text string will be. To do this we simply create a string that represents a Match or MatchCollection object.
Private Function xMatchCollectionToString(ByRef roMatchCollection As MatchCollection) As String
Dim lX As Long
With roMatchCollection
xMatchCollectionToString = ".Count:" & .Count & vbCrLf
For lX = 0 To .Count - 1
xMatchCollectionToString = xMatchCollectionToString _
& "Item " & lX & vbCrLf _
& xMatchToString(.Item(lX))
Next lX
End With
End Function
Private Function xMatchToString(ByRef roMatch As Match) As String
With roMatch
xMatchToString = ".FirstIndex:" & .FirstIndex & vbCrLf _
& " .Length:" & .Length & vbCrLf _
& " .Value:" & .Value & vbCrLf _
& ".SubMatches:" & vbCrLf _
& xSubMatchesToString(.SubMatches) & vbCrLf
End With
End Function
Private Function xSubMatchesToString(ByRef roSubMatches As SubMatches) As String
Dim lX As Long
With roSubMatches
xSubMatchesToString = ".Count:" & .Count & vbCrLf
For lX = 0 To .Count - 1
xSubMatchesToString = xSubMatchesToString _
& "Item " & lX & vbCrLf _
& """" & .Item(lX) & """"
Next lX
End With
End Function
regexptester.vbp
The project file is very simple. No unusual references except the regular expression library.
Type=Exe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\WINNT\System32\stdole2.tlb#OLE Automation
Reference=*\G{3F4DACA7-160D-11D2-A8E9-00104B365C9F}#5.5#0#..\..\..\..\..\..\WINNT\System32\vbscript.dll\3#Microsoft VBScript Regular Expressions 5.5
Form=frmRegExpTester.frm
Startup="frmRegExpTester"
HelpFile=""
Title="prjGet"
Command32="C:\users\kjw\homepage\website\vb\wikirepository\Jarithmetic_Round_Two_Implementation.html"
Name="prjRegExpTester"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName=""
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
Exercises:
- Run the program and see if you can cause it to crash,
- Tidy up the user interface, add accelerator keys to aid navigation, fix the tab order,
- Think of a feature that might be worth adding and add it.
| Previous: Case Studies | Contents | Next: JArithmetic |