Visual Basic/Regular Expression Tester

Introduction edit

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 edit

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 edit

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