Visual Basic/Regular Expression Tester
Introduction
editThis 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
editThis 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
editThe 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 |