1
votes

I'm trying to construct a regular expression using VBScript to extract VBScript method declarations that aren't commented out. For instance, consider the following methods:

Public Function thisContainsACommentedRoutine()
''   Public Sub myRoutine1()
''       print "hello"
''   End Sub
    thisContainsACommentedRoutine = 1 + 1
End Function

'Public Sub myRoutine2()
'    print "routine2"
'End Sub

    Private Sub sub1()
        print "sub1"
    End Sub

I want the following method declarations to be extracted:

Public Function thisContainsACommentedRoutine()
Private Sub sub1()

I tried using the following regular expression (along with many others; I tried researching with negative look-behinds, but they aren't supported in VBScript, so I also tried negative look-aheads):

(?!')(Public|Private) (Function|Sub) .*

using http://regexpal.com, but all the method declarations are being extracted, and I want to ignore any lines that contain the comment character before the method declaration.

The code in the first code block above is returned to me as a whole string, and I'm using VBScript's regular expression object to execute the pattern on the whole string of methods. Also, I'd like to avoid having to process one line at a time to save time.

I tried looking up similar questions (Regular Expression Negative Lookbehind Alternative for VBScript), but somehow the negative lookahead regular expression I'm using is still grabbing the methods that are commented out.

Any suggestions?

EDIT: I'm using .NET's regular expression object instead, and that supports negative lookbehind assertions. I'm now using the following regular expression:

\s*?(?<!')\s*?(Public|Private) (Function|Sub) .*

However, I'm still getting incorrect matches:

Public Function thisContainsACommentedRoutine()
Public Sub myRoutine1()
Private Sub sub1()

The match "Public Sub myRoutine1()" should not be showing up; regardless of the number of spaces before the method, I don't want the method to match if there is at least one comment character (anywhere in the line) before the method declaration.

1

1 Answers

1
votes

VBScript is line orientated. So you can try to exploit that feature by using a Multiline (VBScript) RegExp as in:

  Dim sAll : sAll = goFS.OpenTextFile("..\testdata\subfnc.txt").ReadAll()
  WScript.Echo sAll
  WScript.Echo "--------------"
  Dim reSF : Set reSF = New RegExp
  reSF.Global     = True
  reSF.IgnoreCase = True
  reSF.Multiline  = True
  reSF.Pattern    = "^\s*((?:(?:Public|Private)\s+)?(?:default\s+)?(?:Sub|Function).+)\r$"
  Dim oMT
  For Each oMT in reSF.Execute(sAll)
      WScript.Echo qq(oMT.SubMatches(0))
  Next

output:

Public Function thisContainsACommentedRoutine()
''   Public Sub myRoutine1()
''       print "hello"
''   End Sub
    thisContainsACommentedRoutine = 1 + 1
End Function

'Public Sub myRoutine2()
'    print "routine2"
'End Sub

    Private Sub sub1()
        print "sub1"
        print "Private Sub Sub2(abc)"
    End Sub

         Sub Nix
         End Sub ' Nix

 Public Default Function Zilch(Whatever)
End Function

--------------
"Public Function thisContainsACommentedRoutine()"
"Private Sub sub1()"
"Sub Nix"
"Public Default Function Zilch(Whatever)"

If your code contains Sub/Function declarations spanning lines (_ abomination), you have to pre-process the file(s); then you could remove comments radically (and still use the pattern given above).