WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

String Manipulation

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Regular Expressions UDFs

 Keywords:  regEx Regular expression grep

;===============================================================================================================================================
; udflib.RegExp.wbt  v1.05  20020826  (c)20020708.Detlev Dalitz
;===============================================================================================================================================
; A regular expression is a pattern of text that consists of ordinary characters
; (for example, letters a through z) and special characters, known as metacharacters.
; The pattern describes one or more strings to match when searching a body of text.
; The regular expression serves as a template for matching a character pattern to the string being searched.
;===============================================================================================================================================
;
;   This WinBatch library file contains two sections of 'user defined functions'
;   to provide regular expression search facilities in WinBatch.
;   -  'high level' routines,
;   -  'low level' routines.
;
;   The 'high level' routines hides the VB RegExp object.
;   The properties of the RegExp object must be set by udf parameter list.
;   These functions are the worker functions and will fit for RegExp tasks in general.
;
;   The 'low level' routines allows handling of the RegExp object at object interface level.
;   The 'low level' udfs are mostly simple wrappers (with some overhead in relation to 'pure' object use).
;   The 'low level' functions were build mainly for generalizing the RegExp udf interface.
;
;===============================================================================================================================================



;===============================================================================================================================================
; 'High Level' Routines     (VB Regular Expression object encapsulated)
;===============================================================================================================================================
; udfRegExpTest             (sSearchString, sRegExpPattern, bIgnoreCase)
; udfRegExpMatch            (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, bMultiline, sSepMatchProp, sSepMatchItem)
; udfRegExpReplace          (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch)
;-----------------------------------------------------------------------------------------------------------------------------------------------
; udfRegExpGetMatchCount    (sMatchList, sSepMatchItem)
; udfRegExpGetMatch         (iMatch, sMatchList, sSepMatchItem)
;
; udfRegExpGetMatchValue    (sMatchItem, sSepMatchProp)
; udfRegExpGetMatchIndex    (sMatchItem, sSepMatchProp)
; udfRegExpGetMatchLength   (sMatchItem, sSepMatchProp)
;
; udfRegExpGetSubMatchCount (sRegExpPattern)
; udfRegExpGetSubMatchValue (iSub, sMatchItem, sSepMatchProp)
;===============================================================================================================================================


#DefineFunction udfRegExpGetSubMatchCount (sRegExpPattern)
sRegExpPattern = StrReplace(sRegExpPattern,"\(","")
sRegExpPattern = StrReplace(sRegExpPattern,"\)","")
sRegExpPattern = StrClean(sRegExpPattern,"()","",@TRUE,2)
iCount = StrLen(sRegExpPattern)
If (iCount mod 2) Then Return (-1) ; Error on matching brackets.
Return (iCount/2)
;...............................................................................................................................................
; If opening and closing round brackets do not match (odd count),
; then this udf returns -1 to indicate that there is an error
; on the SubMatching structure in the RegExpPattern.
; Otherwise this udf returns the number of SubMatching parenthesis pairs "()".
;...............................................................................................................................................
#EndFunction


#DefineFunction udfRegExpGetSubMatchValue (iSub, sMatchItem, sSepMatchProp)
If (sSepMatchProp == "") Then sSepMatchProp  = "|"
Return (ItemExtract(3 + iSub,sMatchItem,sSepMatchProp))
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpGetMatchCount (sMatchList, sSepMatchItem)
If (sSepMatchItem == "") Then sSepMatchItem = @TAB
Return (ItemCount(sMatchList,sSepMatchItem))
#EndFunction


#DefineFunction udfRegExpGetMatch (iMatch, sMatchList, sSepMatchItem)
If (sSepMatchItem == "") Then sSepMatchItem = @TAB
Return (ItemExtract(iMatch,sMatchList,sSepMatchItem))
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpGetMatchValue (sMatchItem, sSepMatchProp)
If (sSepMatchProp == "") Then sSepMatchProp  = "|"
Return (ItemExtract(1,sMatchItem,sSepMatchProp))
#EndFunction


#DefineFunction udfRegExpGetMatchIndex (sMatchItem, sSepMatchProp)
If (sSepMatchProp == "") Then sSepMatchProp  = "|"
Return (ItemExtract(2,sMatchItem,sSepMatchProp))
#EndFunction


#DefineFunction udfRegExpGetMatchLength (sMatchItem, sSepMatchProp)
If (sSepMatchProp == "") Then sSepMatchProp  = "|"
Return (ItemExtract(3,sMatchItem,sSepMatchProp))
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpTest (sSearchString, sRegExpPattern, bIgnoreCase)
bResult = @FALSE

LastErrorMode = ErrorMode(@OFF)
LastError()
objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch.
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult Then Goto labelreturn ; Object is not loadable.

objRegExp.Pattern    = sRegExpPattern  ; Set pattern.
objRegExp.IgnoreCase = bIgnoreCase     ; Set case insensitivity. Default is @false.

LastErrorMode = ErrorMode(@OFF)
LastError()
bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult  Then Goto labelobjectclose ; Maybe a pattern definition error.
If !bResult Then Goto labelobjectclose ; There is no match.

:labelobjectclose
ObjectClose(objRegExp)
Drop(objRegExp)

:labelreturn
Return (bResult)
;...............................................................................................................................................
; This udf returns a boolean value depending on the check
; if the sSearchString does have at least one match by sRegExpPattern.
;...............................................................................................................................................
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch)
sString = ""

LastErrorMode = ErrorMode(@OFF)
LastError()
objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch.
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult Then Goto labelreturn ; Object is not loadable.

objRegExp.Pattern    = sRegExpPattern  ; Set pattern.
objRegExp.IgnoreCase = bIgnoreCase     ; Set case insensitivity. Default is @false.
objRegExp.Global     = bGlobalSearch   ; Set global applicability. Default is @false.

LastErrorMode = ErrorMode(@OFF)
LastError()
bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult  Then Goto labelobjectclose ; Maybe a pattern definition error.
If !bResult Then Goto labelobjectclose ; There is no one match.

sString = objRegExp.Replace(sSearchString,sReplaceString) ; Make the replacement.

:labelobjectclose
ObjectClose(objRegExp)
Drop(objRegExp)

:labelreturn
Return (sString)
;...............................................................................................................................................
; Returns an empty string if there was an error on loading the VB Regular Expression OLE object.
; Returns an empty string if there was an error on the RegExpPattern Test.
; If RegExpPattern does match then this udf returns a copy of sSearchString
; with the text of RegExpPattern replaced with ReplaceString.
; If no match is found, a copy of sSearchString is returned unchanged.
;...............................................................................................................................................
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpMatch (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, bMultiline, sSepMatchProp, sSepMatchItem)
MatchList = ""

LastErrorMode = ErrorMode(@OFF)
LastError()
objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch.
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult Then Goto labelreturn ; Object is not loadable.

objRegExp.Pattern    = sRegExpPattern   ; Set pattern.
objRegExp.IgnoreCase = bIgnoreCase      ; Set case insensitivity. Default is @false.
objRegExp.Global     = bGlobalSearch    ; Set global applicability. Default is @false.
objRegExp.Multiline  = bMultiline       ; Set multiline facility. Default is @false.

LastErrorMode = ErrorMode(@OFF)
LastError()
bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult  Then Goto labelobjectclose ; Maybe a pattern definition error.
If !bResult Then Goto labelobjectclose ; There is no one match.

iSubMatchCount = udfRegExpGetSubMatchCount (sRegExpPattern)
If (iSubMatchCount < 0)  Then Goto labelobjectclose ; Maybe a SubMatch definition error.

If (sSepMatchProp == "") Then sSepMatchProp = "|"  ; Set separator between MatchItem properties
If (sSepMatchItem == "") Then sSepMatchItem = @TAB ; Set separator between MatchItems

objMatches = objRegExp.Execute(sSearchString) ; Executes the search. Returns a handle to a Matches collection.

MatchList = ""
hEnum = ObjectCollectionOpen(objMatches) ; Returns an enumeration handle.
While 1
   MatchItem = ""
   objMatch = ObjectCollectionNext(hEnum)   ; Returns a handle to one object which contains a match.
   If !objMatch Then Break

   ; collect properties and build the MatchItem
   MatchItem = ItemInsert(objMatch.Value          ,-1,MatchItem,sSepMatchProp)
   MatchItem = ItemInsert(objMatch.FirstIndex + 1 ,-1,MatchItem,sSepMatchProp) ; force one based index.
   MatchItem = ItemInsert(objMatch.Length         ,-1,MatchItem,sSepMatchProp)

   ; collect the SubMatches
   iSubMatchCountMax = iSubMatchCount - 1
   For iSubMatch=0 To iSubMatchCountMax
      MatchItem = ItemInsert(objMatch.SubMatches(iSubMatch),-1,MatchItem,sSepMatchProp)
   Next

   ; build the MatchList from MatchItems
   MatchList = ItemInsert(MatchItem,-1,MatchList,sSepMatchItem)

   ObjectClose(objMatch)
EndWhile
ObjectCollectionClose(hEnum)
Drop(objMatch,hEnum)

ObjectClose(objMatches)
Drop(objMatches)

:labelobjectclose
ObjectClose(objRegExp)
Drop(objRegExp)

:labelreturn
Return (MatchList)
;...............................................................................................................................................
; Returns an empty string if there was an error on loading the VB Regular Expression OLE object.
; Returns an empty string if there was no match on the search with Regular Expression pattern.
; If RegExpPattern does match Then this udf returns a tab delimited "MatchList" of one or more "MatchItems".
;...............................................................................................................................................
; A MatchItem is a structure of at least three properties: MatchValue, MatchIndex, MatchLength.
; Additionally there are appended SubMatchItems, if captured by the regular expression.
; A MatchItem for itself is a delimited list too, with pipe symbol "|" as default separator.
;
; Example:
; SearchString  = "myabCthis is the second myabcthing"
; RegExpPattern = "(a.*?c)"
; IgnoreCase    = @true
; GlobalSearch  = @true
; MatchList = udfRegExp (SearchString, RegExpPattern, IgnoreCase, GlobalSearch, "", "")
;
; Resulting MatchList contains two MatchItems, each with one SubMatch:
; MatchList = "abC|3|3|abC@TABabc|27|3|abc"
;
; If GlobalSearch is @false Then the resulting MatchList contains only the first MatchItem.
;...............................................................................................................................................
; Note:
; Collection Enumeration is zero based indexed.
; WIL String variables are indexed at 1.
;...............................................................................................................................................
; This udf is based on an article in WinBatch forum by Author "Jim Stiles 20020628 jwstiles@winbatch.com".
; Detlev Dalitz.20020703
;...............................................................................................................................................
#EndFunction




;===============================================================================================================================================
; 'Low Level' Routines      (VB Regular Expression object must be opened and closed manually.)
;===============================================================================================================================================
; udfRegExpOpen             ()                                                           ; returns handle to RegExp object
; udfRegExpClose            (hRegExp)
;
; udfRegExpGetPattern       (hRegExp)                                                    ; returns pattern string
; udfRegExpGetIgnoreCase    (hRegExp)                                                    ; returns boolean value
; udfRegExpGetGlobal        (hRegExp)                                                    ; returns boolean value
; udfRegExpGetMultiline     (hRegExp)                                                    ; returns boolean value
;
; udfRegExpSetPattern       (hRegExp, sPattern)
; udfRegExpSetIgnoreCase    (hRegExp, bIgnoreCase)
; udfRegExpSetGlobal        (hRegExp, bGlobalSearch)
; udfRegExpSetMultiline     (hRegExp, bMultiline)
;
; udfRegExpTestString       (hRegExp, sSearchString)                                     ; returns boolean value
; udfRegExpMatchString      (hRegExp, sSearchString, sSepMatchProp, sSepMatchItem)       ; returns MatchList like udfRegExpMatch
; udfRegExpReplaceString    (hRegExp, sSearchString, sReplaceString)                     ; returns replaced string
;===============================================================================================================================================


#DefineFunction udfRegExpOpen ()
LastErrorMode = ErrorMode(@OFF)
LastError()
objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch.
iResult = LastError()
ErrorMode(LastErrorMode)
Return (objRegExp)
;...............................................................................................................................................
; This udf returns a handle to a RegExp object.
; On error it returns 0.
;...............................................................................................................................................
#EndFunction


#DefineFunction udfRegExpClose (hRegExp)
Return (ObjectClose(hRegExp))
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpGetPattern (hRegExp)
Return (hRegExp.Pattern)
; This udf returns the current pattern setting on a given object handle.
#EndFunction


#DefineFunction udfRegExpGetIgnoreCase (hRegExp)
Return (!!hRegExp.IgnoreCase) ; vbTrue = -1 ; vbFalse = 0
; This udf returns the current IgnoreCase setting on a given object handle.
#EndFunction


#DefineFunction udfRegExpGetGlobal (hRegExp)
Return (!!hRegExp.Global) ; vbTrue = -1 ; vbFalse = 0
; This udf returns the current Global setting on a given object handle.
#EndFunction


#DefineFunction udfRegExpGetMultiline (hRegExp)
Return (!!hRegExp.Multiline) ; vbTrue = -1 ; vbFalse = 0
; This udf returns the current Multiline setting on a given object handle.
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpSetPattern (hRegExp, sPattern)
hRegExp.Pattern = sPattern
#EndFunction


#DefineFunction udfRegExpSetIgnoreCase (hRegExp, bValue)
hRegExp.IgnoreCase = bValue
#EndFunction


#DefineFunction udfRegExpSetGlobal (hRegExp, bValue)
hRegExp.Global = bValue
#EndFunction


#DefineFunction udfRegExpSetMultiline (hRegExp, bValue)
hRegExp.Multiline = bValue
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpTestString (hRegExp, sSearchString)
LastErrorMode = ErrorMode(@OFF)
LastError()
bResult = !!hRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False
iResult = LastError()
ErrorMode(LastErrorMode)
If iResult  Then Return (@FALSE) ; Maybe a pattern definition error.
If !bResult Then Return (@FALSE) ; There is no match.
Return (bResult)
;...............................................................................................................................................
; This udf returns a boolean value depending on the check
; if the sSearchString does have at least one match by previously defined sRegExpPattern.
;...............................................................................................................................................
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------

#DefineFunction udfRegExpReplaceString (hRegExp, sSearchString, sReplaceString)
Return (hRegExp.Replace(sSearchString,sReplaceString))
;...............................................................................................................................................
; If previously defined RegExpPattern does match then this udf returns a copy of sSearchString
; with the text of RegExpPattern replaced with ReplaceString
; If no match is found, a copy of sSearchString is returned unchanged.
;...............................................................................................................................................
#EndFunction

;-----------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfRegExpMatchString (hRegExp, sSearchString, sSepMatchProp, sSepMatchItem)
MatchList = ""

iSubMatchCount = udfRegExpGetSubMatchCount (hRegExp.Pattern)
If (iSubMatchCount < 0)  Then Return ("") ; Maybe a SubMatch definition error.

If (sSepMatchProp == "") Then sSepMatchProp = "|"  ; Set separator between MatchItem properties
If (sSepMatchItem == "") Then sSepMatchItem = @TAB ; Set separator between MatchItems

objMatches = hRegExp.Execute(sSearchString) ; Executes the search. Returns a handle to a Matches collection.

MatchList = ""
hEnum = ObjectCollectionOpen(objMatches) ; Returns an enumeration handle.
While 1
   MatchItem = ""
   objMatch = ObjectCollectionNext(hEnum)   ; Returns a handle to one object which contains a match.
   If !objMatch Then Break

   ; collect properties and build the MatchItem
   MatchItem = ItemInsert(objMatch.Value          ,-1,MatchItem,sSepMatchProp)
   MatchItem = ItemInsert(objMatch.FirstIndex + 1 ,-1,MatchItem,sSepMatchProp) ; force one based index.
   MatchItem = ItemInsert(objMatch.Length         ,-1,MatchItem,sSepMatchProp)

   ; collect the SubMatches
   iSubMatchCountMax = iSubMatchCount - 1
   For iSubMatch=0 To iSubMatchCountMax
      MatchItem = ItemInsert(objMatch.SubMatches(iSubMatch),-1,MatchItem,sSepMatchProp)
   Next

   ; build the MatchList from MatchItems
   MatchList = ItemInsert(MatchItem,-1,MatchList,sSepMatchItem)

   ObjectClose(objMatch)
EndWhile
ObjectCollectionClose(hEnum)
Drop(objMatch,hEnum)

ObjectClose(objMatches)
Drop(objMatches)

Return (MatchList)
#EndFunction
;===============================================================================================================================================



; --- test ---

;-----------------------------------------------------------------------------------------------------------------------------------------------
:test1
;-----------------------------------------------------------------------------------------------------------------------------------------------
; Check if e-mail address format is ok or not.

SearchString  = "dd@dalitz-im-netz.de"
RegExpPattern = "([\w\-]+)@([\w\-]+)\.([\w\-]+)"
IgnoreCase    = @TRUE ; Default is @false.

Match   = udfRegExpTest  (SearchString, RegExpPattern, IgnoreCase)

sNoYes   = ItemExtract(1+Match,"no,yes",",")
sMsgText = StrCat("SearchString matches RegExpPattern =" ,@TAB,sNoYes,@LF)
sMsgText = StrCat("IgnoreCase ="   ,@TAB,IgnoreCase   ,@LF,sMsgText,@LF)
sMsgText = StrCat("RegExpPattern =",@TAB,RegExpPattern,@LF,sMsgText,@LF)
sMsgText = StrCat("SearchString =" ,@TAB,SearchString ,@LF,sMsgText,@LF)

sMsgTitle = "Demo  udfRegExpTest (sSearchString, sRegExpPattern, bIgnoreCase)"
Pause(sMsgTitle,sMsgText)


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test2
;-----------------------------------------------------------------------------------------------------------------------------------------------
; This script uses a regular expression pattern
; to find all the matches for a given pattern
; and returns the matches in a WIL list variable.
; It is an example that shows how the Visual Basic Regular Expression
; capability can be used from WinBatch.
; Original script by Author "Jim Stiles 20020628"

; String with several possible matches for the expression pattern.
; SearchString = "myabCthis is the second myabcthing"
; Match from the first a to and including the next c.
; To exclude the c, try [^c]* in place of .*? .
; To select the string from the first a to the first c, use the ?.
; Without the ?, the expression would select a string from the first a to the final, and third, c.

SearchString  = "myabCthis is the second myabcthing"
RegExpPattern = "(a.*?c)"

IgnoreCase    = @TRUE  ; Default is @false.
GlobalSearch  = @TRUE  ; Default is @false.
Multiline     = @FALSE ; Default is @false.

SepMatchProp = "|"
SepMatchList = @TAB

MatchList = udfRegExpMatch (SearchString, RegExpPattern, IgnoreCase, GlobalSearch, Multiline, SepMatchProp, SepMatchList)

iCount = udfRegExpGetMatchCount (MatchList, SepMatchList)
sMsgText  = ""
For i=1 To iCount
   Match  = udfRegExpGetMatch  (i, MatchList, SepMatchList)
   Value  = udfRegExpGetMatchValue  (Match, SepMatchProp)
   Index  = udfRegExpGetMatchIndex  (Match, SepMatchProp)
   Length = udfRegExpGetMatchLength (Match, SepMatchProp)

   sMsgText  = StrCat(sMsgText,"Value =" ,@TAB,Value ,@TAB)
   sMsgText  = StrCat(sMsgText,"Index =" ,@TAB,Index ,@TAB)
   sMsgText  = StrCat(sMsgText,"Length =",@TAB,Length,@TAB)
   sMsgText  = StrCat(sMsgText,@LF)
Next
sMsgText = StrCat("GlobalSearch =" ,@TAB,GlobalSearch ,@LF,@LF,sMsgText,@LF)
sMsgText = StrCat("IgnoreCase ="   ,@TAB,IgnoreCase   ,@LF,sMsgText,@LF)
sMsgText = StrCat("RegExpPattern =",@TAB,RegExpPattern,@LF,sMsgText,@LF)
sMsgText = StrCat("SearchString =" ,@TAB,SearchString ,@LF,sMsgText,@LF)

sMsgTitle = "Demo  udfRegExpFind (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, sSepMatchProp, sSepMatchItem)"
Pause(sMsgTitle,sMsgText)


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test3
;-----------------------------------------------------------------------------------------------------------------------------------------------
; Check e-mail address and separate it into three parts.

SearchString  = "Please send mail to drag_on@x-yz-zy.com. Thanks!"
RegExpPattern = "([\w\-]+)@([\w\-]+)\.([\w\-]+)"
; RegExpPattern = "([\w])+" ; test it!

IgnoreCase    = @FALSE
GlobalSearch  = @FALSE
Multiline     = @FALSE

IgnoreCase    = @TRUE
GlobalSearch  = @TRUE

SepMatchProp = "|"
SepMatchList = @TAB

MatchList  = udfRegExpMatch (SearchString, RegExpPattern, IgnoreCase, GlobalSearch, Multiline, SepMatchProp, SepMatchList)
MatchCount = udfRegExpGetMatchCount (MatchList, SepMatchList)
SubCount   = udfRegExpGetSubMatchCount (RegExpPattern)

sMsgText  = ""

For iMatch=1 To MatchCount
   Match  = udfRegExpGetMatch  (iMatch, MatchList, SepMatchList)
   Value  = udfRegExpGetMatchValue  (Match, SepMatchProp)
   Index  = udfRegExpGetMatchIndex  (Match, SepMatchProp)
   Length = udfRegExpGetMatchLength (Match, SepMatchProp)

   sMsgText  = StrCat(sMsgText,'Value'  ,@TAB,' = ','"',Value ,'"',@TAB)
   sMsgText  = StrCat(sMsgText,'Index'  ,@TAB,' = ','"',Index ,'"',@TAB)
   sMsgText  = StrCat(sMsgText,'Length' ,@TAB,' = ','"',Length,'"',@TAB)
   sMsgText  = StrCat(sMsgText,@LF)

   For iSub=1 To SubCount
      SubMatch = udfRegExpGetSubMatchValue (iSub, Match, SepMatchProp)
      sMsgText  = StrCat(sMsgText,'SubMatch',iSub,@TAB,' = ','"',SubMatch,'"',@LF)
   Next
Next

sMsgText = StrCat('GlobalSearch' ,@TAB,' = ','"',GlobalSearch ,'"',@LF,@LF,sMsgText,@LF)
sMsgText = StrCat('IgnoreCase'   ,@TAB,' = ','"',IgnoreCase   ,'"',@LF,sMsgText,@LF)
sMsgText = StrCat('RegExpPattern',@TAB,' = ','"',RegExpPattern,'"',@LF,sMsgText,@LF)
sMsgText = StrCat('SearchString' ,@TAB,' = ','"',SearchString ,'"',@LF,sMsgText,@LF)

sMsgTitle = "Demo  udfRegExp (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, sSepMatchProp, sSepMatchItem)"
Pause(sMsgTitle,sMsgText)


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test4
;-----------------------------------------------------------------------------------------------------------------------------------------------
; Replace one word with another word.

SearchString  = "The quick brown fox jumped over the lazy dog."
RegExpPattern = "fox"
ReplaceString = "cat"

IgnoreCase    = @TRUE
GlobalSearch  = @FALSE

ReplacedString = udfRegExpReplace (SearchString, RegExpPattern, ReplaceString, IgnoreCase, GlobalSearch)

sMsgTitle = "Demo  udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)"
sMsgText = ""
sMsgText = StrCat(sMsgText,'SearchString'  ,@TAB,' = ','"',SearchString  ,'"',@LF)
sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',RegExpPattern ,'"',@LF)
sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',ReplaceString ,'"',@LF)
sMsgText = StrCat(sMsgText,'IgnoreCase'    ,@TAB,' = ','"',IgnoreCase    ,'"',@LF)
sMsgText = StrCat(sMsgText,'GlobalSearch'  ,@TAB,' = ','"',GlobalSearch  ,'"',@LF)
sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',ReplacedString,'"',@LF)
Pause(sMsgTitle,sMsgText)


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test5
;-----------------------------------------------------------------------------------------------------------------------------------------------
; In addition, the Replace method can replace subexpressions in the pattern.
; The following script swaps each pair of words in the original string

SearchString  = "The quick brown fox jumped over the lazy dog."
RegExpPattern = "(\S+)(\s+)(\S+)" ; Swap pairs of words.
ReplaceString = "$3$2$1"

IgnoreCase    = @TRUE
GlobalSearch  = @TRUE

ReplacedString = udfRegExpReplace (SearchString, RegExpPattern, ReplaceString, IgnoreCase, GlobalSearch)

sMsgTitle = "Demo  udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)"
sMsgText = ""
sMsgText = StrCat(sMsgText,'SearchString'  ,@TAB,' = ','"',SearchString  ,'"',@LF)
sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',RegExpPattern ,'"',@LF)
sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',ReplaceString ,'"',@LF)
sMsgText = StrCat(sMsgText,'IgnoreCase'    ,@TAB,' = ','"',IgnoreCase    ,'"',@LF)
sMsgText = StrCat(sMsgText,'GlobalSearch'  ,@TAB,' = ','"',GlobalSearch  ,'"',@LF)
sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',ReplacedString,'"',@LF)
Pause(sMsgTitle,sMsgText)


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test6
;-----------------------------------------------------------------------------------------------------------------------------------------------
; Set and query RegExp properties.

objRegExp = udfRegExpOpen ()

If (objRegExp <> 0)

   udfRegExpSetPattern(objRegExp,"( *)next( *)")
   udfRegExpSetIgnoreCase(objRegExp, @TRUE)
   udfRegExpSetGlobal(objRegExp, @FALSE)
   udfRegExpSetMultiline(objRegExp, @TRUE)


   sMsgTitle = "Demo  udfRegExpGetPattern ()"
   sMsgText = ""
   sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',udfRegExpGetPattern(objRegExp)   ,'"',@LF)
   sMsgText = StrCat(sMsgText,'IgnoreCase'    ,@TAB,' = ','"',udfRegExpGetIgnoreCase(objRegExp),'"',@LF)
   sMsgText = StrCat(sMsgText,'GlobalSearch'  ,@TAB,' = ','"',udfRegExpGetGlobal(objRegExp)    ,'"',@LF)
   sMsgText = StrCat(sMsgText,'MultiLine'     ,@TAB,' = ','"',udfRegExpGetMultiline(objRegExp) ,'"',@LF)
   Pause(sMsgTitle,sMsgText)

   udfRegExpClose (objRegExp)
EndIf


;-----------------------------------------------------------------------------------------------------------------------------------------------
:test7
;-----------------------------------------------------------------------------------------------------------------------------------------------
; Replace control character.

SearchString  = StrCat("Control",@CR,"characters",@LF,"can also be indicated",@CR,@LF,"by RegExp pattern.",@CRLF)
RegExpPattern = "(\cM\cJ)|(\cJ)|(\cM)"     ; @cr@lf or @lf or @cr
ReplaceString = "
" IgnoreCase = @TRUE GlobalSearch = @TRUE ReplacedString = udfRegExpReplace (SearchString, RegExpPattern, ReplaceString, IgnoreCase, GlobalSearch) sMsgTitle = "Demo udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)" sMsgText = "" sMsgText = StrCat(sMsgText,'SearchString' ,@TAB,' = ','"',SearchString ,'"',@LF) sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',RegExpPattern ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',ReplaceString ,'"',@LF) sMsgText = StrCat(sMsgText,'IgnoreCase' ,@TAB,' = ','"',IgnoreCase ,'"',@LF) sMsgText = StrCat(sMsgText,'GlobalSearch' ,@TAB,' = ','"',GlobalSearch ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',ReplacedString,'"',@LF) Pause(sMsgTitle,sMsgText) ;----------------------------------------------------------------------------------------------------------------------------------------------- :CANCEL Exit ;----------------------------------------------------------------------------------------------------------------------------------------------- ;=============================================================================================================================================== ; Requirements ;=============================================================================================================================================== ; This WIL User Defined Function library is based on the OLE object "VBScript.RegExp". ; It requires "Microsoft Visual Basic Scripting Edition Version 5.0/5.5" ; implemented by Host Application "Microsoft Internet Explorer 5.0/5.5". ; The SubMatch collection requires "Microsoft Visual Basic Scripting Edition Version 5.5" ; The Multiline property requires "Microsoft Visual Basic Scripting Edition Version 5.5" ; Some Replace Properties require "Microsoft Internet Explorer 5.5" or "Microsoft Windows Millennium Edition" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Original documentation adapted from the Microsoft Platform SDK, May 2002 Edition. ;=============================================================================================================================================== ;=============================================================================================================================================== ; Here are some examples of regular expression you might encounter ;=============================================================================================================================================== ; Match a blank line. ; "^\s*$" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Validate an ID number consisting of 2 digits, a hyphen, and another 5 digits. ; "\d{2}-\d{5}" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Validate an email address in the format "name@host.org". ; "([\w\-]+)@([\w\-]+)\.([\w\-]+)" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Match "industry" or "industries" (non-capturing match). ; "industr(?:y|ies)" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Match "Windows" in "Windows 2000" but not "Windows" in "Windows 3.1" ; (non-capturing match, positive lookahead). ; "Windows (?=95|98|NT|2000)" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Match "Windows" in "Windows 3.1" but does not match "Windows" in "Windows 2000" ; (non-capturing match, negative lookahead). ; "Windows (?!95|98|NT|2000)" ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Match the copyright symbol (©). ; "\u00A9" ;=============================================================================================================================================== ;=============================================================================================================================================== ; Additional notes from the MS SDK, Visual Basic Scripting Edition ;=============================================================================================================================================== ; ObjectRegExp.Pattern [= "searchstring"] ; The "Pattern Property" sets or returns the regular expression pattern being searched for. ; Optional searchstring is a regular string expression being searched for. ; May include any of the regular expression characters defined in the table in the "Settings" section. ; ; ObjectRegExp.IgnoreCase [= True | False ] ; The "IgnoreCase Property" sets or returns a Boolean value that indicates ; if a pattern search is case-sensitive or not. ; The value of the IgnoreCase property is False if the search is case-sensitive, ; True if it is not. Default is False. ; ; ObjectRegExp.Global [= True | False ] ; The "Global Property" sets or returns a Boolean value that indicates ; if a pattern should match all occurrences in an entire search string or just the first one. ; The object argument is always a RegExp object. ; The value of the Global property is True if the search applies to the entire string, ; False if it does not. Default is False. ; ; ObjectRegExp.Multiline [= True | False ] ; ??? ; If multiline is false, ; "^" matches the position at the beginning of a string, and ; "$" matches the position at the end of a string. ; If multline is true, ; "^" matches the position at the beginning of a string as well as the position following a "\n" or "\r", ; and "$" matches the position at the end of a string and the position preceding "\n" or "\r". ; Default is False. ; ; ObjectRegExp.Execute (string) ; ??? ; ; ObjectRegExp.Test (string) ; The "Test Method" executes a regular expression search against a specified string ; and returns a Boolean value that indicates if a pattern match was found. ; The actual pattern for the regular expression search is set using the Pattern property of the RegExp object. ; The RegExp.Global property has no effect on the Test method. ; The Test method returns True if a pattern match is found; False if no match is found. ; ; ObjectRegExp.Replace (string1, string2) ; The Replace Method replaces text found in a regular expression search. ; String1 is the text string in which the text replacement is to occur. ; String2 is the replacement text string. ; The actual pattern for the text being replaced is set using the Pattern property of the RegExp object. ; The Replace method returns a copy of string1 with the text of RegExp.Pattern replaced with string2. ; If no match is found, a copy of string1 is returned unchanged. ; ; In addition, the Replace method can replace subexpressions in the pattern. ; e.g. ObjectRegExp.Replace("(\S+)(\s+)(\S+)", "$3$2$1")) swaps pairs of words. ; For further details see "Replace Properties" section. ; ;=============================================================================================================================================== ;=============================================================================================================================================== ; Settings ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Special characters and sequences are used in writing patterns for regular expressions. ; The following table describes and gives an example of the characters and sequences that can be used. ; ; Character Description ; ; \ Marks the next character as a special character, a literal, a backreference, or an octal escape. ; For example, "n" matches the character "n". ; "\n" matches a newline character. ; The sequence "\\" matches "\" and "\(" matches "(". ; ; ^ Matches the position at the beginning of the input string. ; If the RegExp object's Multiline property is set, ; ^ also matches the position following "\n" or "\r". ; ; $ Matches the position at the end of the input string. ; If the RegExp object's Multiline property is set, ; $ also matches the position preceding "\n" or "\r". ; ; * Matches the preceding character zero or more times. ; For example, "zo*" matches either "z" or "zoo". ; * is equivalent to "{0,}". ; ; + Matches the preceding character one or more times. ; For example, "zo+" matches "zoo" but not "z". ; + is equivalent to "{1,}". ; ; ? Matches the preceding character zero or one time. ; For example, "a?ve?" matches the "ve" in "never". ; For example, "do(es)?" matches the "do" in "do" or "does". ; ? is equivalent to "{0,1}" ; When this character immediately follows any of the other quantifiers ; (*, +, ?, {n}, {n,}, {n,m}), the matching pattern is non-greedy. ; A non-greedy pattern matches as little of the searched string as possible, ; whereas the default greedy pattern matches as much of the searched string as possible. ; For example, in the string "oooo", 'o+?' matches a single "o", while 'o+' matches all 'o's. ; ; . Matches any single character except a newline character "\n". ; To match any character including the "\n", use a pattern such as "[\s\S]". ; ; (pattern) Matches pattern and remembers the match. ; The matched substring can be retrieved from the resulting Matches collection, using Item [0]...[n]. ; To match parentheses characters ( ), use "\(" or "\)". ; ; (?:pattern) Matches pattern but does not capture the match, ; that is, it is a non-capturing match that is not stored for possible later use. ; This is useful for combining parts of a pattern with the "or" character (|). ; For example, 'industr(?:y|ies) is a more economical expression than 'industry|industries'. ; ; (?=pattern) Positive lookahead matches the search string at any point where a string matching pattern begins. ; This is a non-capturing match, that is, the match is not captured for possible later use. ; For example 'Windows (?=95|98|NT|2000)' matches "Windows" in "Windows 2000" ; but not "Windows" in "Windows 3.1". ; Lookaheads do not consume characters, that is, after a match occurs, ; the search for the next match begins immediately following the last match, ; not after the characters that comprised the lookahead. ; ; (?!pattern) Negative lookahead matches the search string at any point where a string not matching pattern begins. ; This is a non-capturing match, that is, the match is not captured for possible later use. ; For example 'Windows (?!95|98|NT|2000)' matches "Windows" in "Windows 3.1" ; but does not match "Windows" in "Windows 2000". ; Lookaheads do not consume characters, that is, after a match occurs, ; the search for the next match begins immediately following the last match, ; not after the characters that comprised the lookahead. ; ; x|y Matches either x or y. For example, 'z|food' matches "z" or "food". '(z|f)ood' matches "zood" or "food". ; ; {n} n is a nonnegative integer. ; Matches exactly n times. ; For example, "o{2}" does not match the "o" in "Bob," but matches the first two o's in "foooood". ; ; {n,} n is a nonnegative integer. ; Matches at least n times. ; For example, "o{2,}" does not match the "o" in "Bob" and matches all the o's in "foooood." ; "o{1,}" is equivalent to "o+". ; "o{0,}" is equivalent to "o*". ; ; {n,m} m and n are nonnegative integers, where n <= m. ; Matches at least n and at most m times. ; For example, "o{1,3}" matches the first three o's in "fooooood". ; "o{0,1}" is equivalent to "o?". ; Note that you cannot put a space between the comma and the numbers. ; ; [xyz] A character set. Matches any one of the enclosed characters. ; For example, "[abc]" matches the "a" in "plain". ; ; [^xyz] A negative character set. Matches any character not enclosed. ; For example, "[^abc]" matches the "p" in "plain". ; ; [a-z] A range of characters. Matches any character in the specified range. ; For example, "[a-z]" matches any lowercase alphabetic character in the range "a" through "z". ; ; [^m-z] A negative range characters. Matches any character not in the specified range. ; For example, "[m-z]" matches any character not in the range "m" through "z". ; ; \b Matches a word boundary, that is, the position between a word and a space. ; For example, "er\b" matches the "er" in "never" but not the "er" in "verb". ; ; \B Matches a non-word boundary. "ea*r\B" matches the "ear" in "never early". ; ; \d Matches a digit character. Equivalent to "[0-9]". ; ; \D Matches a non-digit character. Equivalent to "[^0-9]". ; ; \f Matches a form-feed character. Equivalent to "\x0c" and "\cL". ; ; \n Matches a newline character. Equivalent to "\x0a" and "\cJ". ; ; \r Matches a carriage return character. Equivalent to "\x0d" and "\cM". ; ; \s Matches any white space including space, tab, form-feed, etc. Equivalent to "[ \f\n\r\t\v]". ; ; \S Matches any nonwhite space character. Equivalent to "[^ \f\n\r\t\v]". ; ; \t Matches a tab character. Equivalent to "\x09" and "\cI". ; ; \v Matches a vertical tab character. Equivalent to "\x0b" and "\cK". ; ; \w Matches any word character including underscore. Equivalent to "[A-Za-z0-9_]". ; ; \W Matches any non-word character. Equivalent to "[^A-Za-z0-9_]". ; ; \num Matches num, where num is a positive integer. A reference back to remembered matches. ; For example, "(.)\1" matches two consecutive identical characters. ; If \num is preceded by at least num captured subexpressions, num is a backreference. ; Otherwise, num is an octal escape value if num is an octal digit (0-7). ; ; \n Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. ; For example, "\11" and "\011" both match a tab character. ; "\0011" is the equivalent of "\001" & "1". Octal escape values must not exceed 256. ; If they do, only the first two digits comprise the expression. ; Allows ASCII codes to be used in regular expressions. ; ; \nm Identifies either an octal escape value or a backreference. ; If \nm is preceded by at least nm captured subexpressions, nm is a backreference. ; If \nm is preceded by at least n captures, n is a backreference followed by literal m. ; If neither of the preceding conditions exist, ; \nm matches octal escape value nm when n and m are octal digits (0-7). ; ; \nml Matches octal escape value nml when n is an octal digit (0-3) and m and l are octal digits (0-7). ; ; \xn Matches n, where n is a hexadecimal escape value. ; Hexadecimal escape values must be exactly two digits long. ; For example, "\x41" matches "A". "\x041" is equivalent to "\x04" & "1". ; Allows ASCII codes to be used in regular expressions. ; ; \cx Matches the control character indicated by x. ; For example, \cM matches a Control-M or carriage return character. ; The value of x must be in the range of A-Z or a-z. ; If not, c is assumed to be a literal 'c' character. ; ; \un Matches n, where n is a Unicode character expressed as four hexadecimal digits. ; For example, \u00A9 matches the copyright symbol (©). ; ;=============================================================================================================================================== ;=============================================================================================================================================== ; Replace Properties ;----------------------------------------------------------------------------------------------------------------------------------------------- ; $1...$9 $1...$9 properties ; Returns the nine most-recently memorized portions found during pattern matching. Read-only. ; The value of the $1...$9 properties is modified whenever a successful parenthesized match is made. ; Any number of parenthesized substrings may be specified in a regular expression pattern, ; but only the nine most recent can be stored. ; ; $_ input Property ; Returns the string against which a regular expression search was performed. Read-only. ; The value of input property is modified any time the searched string is changed. ; ; $& lastMatch Property ; Returns the last matched characters from any regular expression search. Read-only. ; The initial value of the lastMatch property is an empty string. ; The value of the lastMatch property changes whenever a successful match is made. ; ; $+ lastParen Property ; Returns the last parenthesized submatch from any regular expression search, if any. Read-only. ; The initial value of the lastParen property is an empty string. ; The value of the lastParen property changes whenever a successful match is made. ; ; $` leftContext Property ; Returns the characters from the beginning of a searched string ; up to the position before the beginning of the last match. Read-only. ; The initial value of the leftContext property is an empty string. ; The value of the leftContext property changes whenever a successful match is made. ; ; $' rightContext Property ; Returns the characters from the position following the last match to the end of the searched string. Read-only. ; The initial value of the rightContext property is an empty string. ; The value of the rightContext property changes whenever a successful match is made. ; ;=============================================================================================================================================== ;=============================================================================================================================================== ; Control Characters Table ;=============================================================================================================================================== ; Decimal Binary Hex Ascii Key ; ; 0 00000000 00 NUL ; 1 00000001 01 SOH ^A ; 2 00000010 02 STX ^B ; 3 00000011 03 ETX ^C ; 4 00000100 04 EOT ^D ; 5 00000101 05 ENQ ^E ; 6 00000110 06 ACK ^F ; 7 00000111 07 BEL ^G ; 8 00001000 08 BS ^H ; 9 00001001 09 HT ^I ; 10 00001010 0A LF ^J ; 11 00001011 0B VT ^K ; 12 00001100 0C FF ^L ; 13 00001101 0D CR ^M ; 14 00001110 0E SO ^N ; 15 00001111 0F SI ^O ; 16 00010000 10 DLE ^P ; 17 00010001 11 DC1 ^Q ; 18 00010010 12 DC2 ^R ; 19 00010011 13 DC3 ^S ; 20 00010100 14 DC4 ^T ; 21 00010101 15 NAK ^U ; 22 00010110 16 SYN ^V ; 23 00010111 17 ETB ^W ; 24 00011000 18 CAN ^X ; 25 00011001 19 EM ^Y ; 26 00011010 1A SUB ^Z ; 27 00011011 1B ESC ^[ ; 28 00011100 1C FS ^\ ; 29 00011101 1D GS ^] ; 30 00011110 1E RS ^^ ; 31 00011111 1F US ^_ ;===============================================================================================================================================

Article ID:   W15738
File Created: 2003:05:13:11:29:54
Last Updated: 2003:05:13:11:29:54