REGEXP.WBT v1.06 20030917
The following WinBatch 'User Defined Functions' make use of the Visual Basic Scripting Edition OLE object 'VBScript.RegExp' to support Regular Expressions in WinBatch scripts. |
If you have questions about WinBatch, you are encouraged to use online WebBoard BBS at http://webboard.windowware.com |
;=============================================================================================================================================== ; udflib.RegExp.wbt v1.06 20030917 (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 hide 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 allow 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, sMatchPropSep, sMatchItemSep) ; udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch) ;----------------------------------------------------------------------------------------------------------------------------------------------- ; udfRegExpGetMatchCount (sMatchList, sMatchItemSep) ; udfRegExpGetMatch (iMatch, sMatchList, sMatchItemSep) ; ; udfRegExpGetMatchValue (sMatchItem, sMatchPropSep) ; udfRegExpGetMatchIndex (sMatchItem, sMatchPropSep) ; udfRegExpGetMatchLength (sMatchItem, sMatchPropSep) ; ; udfRegExpGetSubMatchCount (sMatchItem, sMatchPropSep) ; udfRegExpGetSubMatchValue (iSub, sMatchItem, sMatchPropSep) ; ; udfRegExpCheckPattern (sRegExpPattern) ;=============================================================================================================================================== ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpCheckPattern (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 udfRegExpGetSubMatchCount (sMatchItem,sMatchPropSep) Return (ItemCount(sMatchItem,sMatchPropSep)-3) ;............................................................................................................................................... ; This udf returns the number of SubMatch items per given MatchItem. ;............................................................................................................................................... #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetSubMatchValue (iSub, sMatchItem, sMatchPropSep) If (sMatchPropSep == "") Then sMatchPropSep = "|" Return (ItemExtract(3 + iSub,sMatchItem,sMatchPropSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetMatchCount (sMatchList, sMatchItemSep) If (sMatchItemSep == "") Then sMatchItemSep = @TAB Return (ItemCount(sMatchList,sMatchItemSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetMatch (iMatch, sMatchList, sMatchItemSep) If (sMatchItemSep == "") Then sMatchItemSep = @TAB Return (ItemExtract(iMatch,sMatchList,sMatchItemSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetMatchValue (sMatchItem, sMatchPropSep) If (sMatchPropSep == "") Then sMatchPropSep = "|" Return (ItemExtract(1,sMatchItem,sMatchPropSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetMatchIndex (sMatchItem, sMatchPropSep) If (sMatchPropSep == "") Then sMatchPropSep = "|" Return (ItemExtract(2,sMatchItem,sMatchPropSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpGetMatchLength (sMatchItem, sMatchPropSep) If (sMatchPropSep == "") Then sMatchPropSep = "|" Return (ItemExtract(3,sMatchItem,sMatchPropSep)) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpTest (sSearchString, sRegExpPattern, bIgnoreCase) bResult = @FALSE iLastErrorMode = ErrorMode(@OFF) LastError() objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch. iResult = LastError() ErrorMode(iLastErrorMode) If iResult Then Goto LABELRETURN ; Object is not loadable. objRegExp.Pattern = sRegExpPattern ; Set pattern. objRegExp.IgnoreCase = bIgnoreCase ; Set case insensitivity. Default is @FALSE. iLastErrorMode = ErrorMode(@OFF) LastError() bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False iResult = LastError() ErrorMode(iLastErrorMode) 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 SearchString does have at least one match by RegExpPattern. ;............................................................................................................................................... #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch) sString = "" iLastErrorMode = ErrorMode(@OFF) LastError() objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch. iResult = LastError() ErrorMode(iLastErrorMode) 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. iLastErrorMode = ErrorMode(@OFF) LastError() bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False iResult = LastError() ErrorMode(iLastErrorMode) 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 sRegExpPattern Test. ; If RegExpPattern does match, then this udf returns a copy of SearchString ; with the text of RegExpPattern replaced with ReplaceString. ; If no match is found, a copy of SearchString is returned unchanged. ;............................................................................................................................................... #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpMatch (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, bMultiLine, sMatchPropSep, sMatchItemSep) sMatchList = "" iLastErrorMode = ErrorMode(@OFF) LastError() objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch. iResult = LastError() ErrorMode(iLastErrorMode) 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. iLastErrorMode = ErrorMode(@OFF) LastError() bResult = !!objRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False iResult = LastError() ErrorMode(iLastErrorMode) If iResult Then Goto LABELOBJECTCLOSE ; Maybe a pattern definition error. If !bResult Then Goto LABELOBJECTCLOSE ; There is no one match. iSubMatchCount = udfRegExpCheckPattern (sRegExpPattern) If (iSubMatchCount < 0) Then Goto LABELOBJECTCLOSE ; Maybe a SubMatch definition error. If (sMatchPropSep == "") Then sMatchPropSep = "|" ; Set separator between MatchItem properties If (sMatchItemSep == "") Then sMatchItemSep = @TAB ; Set separator between MatchItems objMatches = objRegExp.Execute(sSearchString) ; Executes the search. Returns a handle to a Matches collection. sMatchList = "" hEnum = ObjectCollectionOpen(objMatches) ; Returns an enumeration handle. While @TRUE sMatchItem = "" objMatch = ObjectCollectionNext(hEnum) ; Returns a handle to one object which contains a match. If !objMatch Then Break ; Collect properties and build the MatchItem. sMatchItem = ItemInsert(objMatch.Value ,-1,sMatchItem,sMatchPropSep) sMatchItem = ItemInsert(objMatch.FirstIndex + 1 ,-1,sMatchItem,sMatchPropSep) ; Force one based index. sMatchItem = ItemInsert(objMatch.Length ,-1,sMatchItem,sMatchPropSep) ; Collect the SubMatches. objSubMatches = objMatch.SubMatches iSubMatchCountMax = objSubMatches.count - 1 For iSubMatch=0 To iSubMatchCountMax sMatchItem = ItemInsert(objSubMatches.Item(iSubMatch),-1,sMatchItem,sMatchPropSep) Next ObjectClose(objSubMatches) ; Build the MatchList from MatchItems. sMatchList = ItemInsert(sMatchItem,-1,sMatchList,sMatchItemSep) ObjectClose(objMatch) EndWhile ObjectCollectionClose(hEnum) Drop(objMatch,objSubMatches,hEnum) ObjectClose(objMatches) Drop(objMatches) :LABELOBJECTCLOSE ObjectClose(objRegExp) Drop(objRegExp) :LABELRETURN Return (sMatchList) ;............................................................................................................................................... ; 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, when captured by the regular expression. ; A MatchItem for itself is a delimited list too, with pipe symbol "|" as default separator. ; ; Example: ; sSearchString = "myabCthis is the second myabcthing" ; sRegExpPattern = "(a.*?c)" ; bIgnoreCase = @true ; bGlobalSearch = @true ; sMatchList = udfRegExp (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, "", "") ; ; Resulting MatchList contains two MatchItems, each with one SubMatch: ; sMatchList = "abC|3|3|abC@TABabc|27|3|abc" ; ; If bGlobalSearch 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, sMatchPropSep, sMatchItemSep) ; Returns MatchList like udfRegExpMatch. ; udfRegExpReplaceString (hRegExp, sSearchString, sReplaceString) ; Returns replaced string. ;=============================================================================================================================================== ;----------------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfRegExpOpen () iLastErrorMode = ErrorMode(@OFF) LastError() objRegExp = ObjectOpen("VBScript.RegExp") ; Creates a regular expression object for use by WinBatch. iResult = LastError() ErrorMode(iLastErrorMode) 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 bIgnoreCase 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 bMultiLine 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) iLastErrorMode = ErrorMode(@OFF) LastError() bResult = !!hRegExp.Test(sSearchString) ; vbTrue -1 True ; vbFalse 0 False iResult = LastError() ErrorMode(iLastErrorMode) 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 SearchString ; 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, sMatchPropSep, sMatchItemSep) sMatchList = "" iSubMatchCount = udfRegExpCheckPattern (sRegExpPattern) If (iSubMatchCount < 0) Then Return ("") ; Maybe a SubMatch definition error. If (sMatchPropSep == "") Then sMatchPropSep = "|" ; Set separator between MatchItem properties. If (sMatchItemSep == "") Then sMatchItemSep = @TAB ; Set separator between MatchItems. objMatches = hRegExp.Execute(sSearchString) ; Executes the search. Returns a handle to a Matches collection. sMatchList = "" hEnum = ObjectCollectionOpen(objMatches) ; Returns an enumeration handle. While @TRUE sMatchItem = "" objMatch = ObjectCollectionNext(hEnum) ; Returns a handle to one object which contains a match. If !objMatch Then Break ; Collect properties and build the MatchItem. sMatchItem = ItemInsert(objMatch.Value ,-1,sMatchItem,sMatchPropSep) sMatchItem = ItemInsert(objMatch.FirstIndex + 1 ,-1,sMatchItem,sMatchPropSep) ; Force one based index. sMatchItem = ItemInsert(objMatch.Length ,-1,sMatchItem,sMatchPropSep) ; Collect the SubMatches. objSubMatches = objMatch.SubMatches iSubMatchCountMax = objSubMatches.count - 1 For iSubMatch=0 To iSubMatchCountMax sMatchItem = ItemInsert(objSubMatches.Item(iSubMatch),-1,sMatchItem,sMatchPropSep) Next ObjectClose(objSubMatches) ; Build the MatchList from MatchItems. sMatchList = ItemInsert(sMatchItem,-1,sMatchList,sMatchItemSep) ObjectClose(objMatch) EndWhile ObjectCollectionClose(hEnum) Drop(objMatch,objSubMatches,hEnum) ObjectClose(objMatches) Drop(objMatches) Return (sMatchList) #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------------- ;=============================================================================================================================================== ; --- test --- ;----------------------------------------------------------------------------------------------------------------------------------------------- :test1 ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Check if e-mail address format is ok or not. sSearchString = "dd@dalitz-im-netz.de" sRegExpPattern = "([\w\-]+)@([\w\-]+)\.([\w\-]+)" bIgnoreCase = @TRUE ; Default is @FALSE. iMatched = udfRegExpTest (sSearchString, sRegExpPattern, bIgnoreCase) sNoYes = ItemExtract(1+iMatched,"no,yes",",") sMsgText = StrCat("SearchString matches RegExpPattern =" ,@TAB,sNoYes,@LF) sMsgText = StrCat("IgnoreCase =" ,@TAB,bIgnoreCase ,@LF,sMsgText,@LF) sMsgText = StrCat("RegExpPattern =",@TAB,sRegExpPattern,@LF,sMsgText,@LF) sMsgText = StrCat("SearchString =" ,@TAB,sSearchString ,@LF,sMsgText,@LF) sMsgTitle = "Demo udfRegExpTest (sSearchString, sRegExpPattern, bIgnoreCase)" IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :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. ; sSearchString = "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. sSearchString = "myabCthis is the second myabcthing" sRegExpPattern = "(a.*?c)" bIgnoreCase = @TRUE ; Default is @FALSE. bGlobalSearch = @TRUE ; Default is @FALSE. bMultiLine = @FALSE ; Default is @FALSE. sMatchPropSep = "|" sMatchListSep = @TAB sMatchList = udfRegExpMatch (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, bMultiLine, sMatchPropSep, sMatchListSep) iCount = udfRegExpGetMatchCount (sMatchList, sMatchListSep) sMsgText = "" For i=1 To iCount sMatch = udfRegExpGetMatch (i, sMatchList, sMatchListSep) sValue = udfRegExpGetMatchValue (sMatch, sMatchPropSep) iIndex = udfRegExpGetMatchIndex (sMatch, sMatchPropSep) iLength = udfRegExpGetMatchLength (sMatch, sMatchPropSep) sMsgText = StrCat(sMsgText,"Value =" ,@TAB,sValue ,@TAB) sMsgText = StrCat(sMsgText,"Index =" ,@TAB,iIndex ,@TAB) sMsgText = StrCat(sMsgText,"Length =",@TAB,iLength,@TAB) sMsgText = StrCat(sMsgText,@LF) Next sMsgText = StrCat("GlobalSearch =" ,@TAB,bGlobalSearch ,@LF,@LF,sMsgText,@LF) sMsgText = StrCat("IgnoreCase =" ,@TAB,bIgnoreCase ,@LF,sMsgText,@LF) sMsgText = StrCat("MultiLine =" ,@TAB,bMultiLine ,@LF,sMsgText,@LF) sMsgText = StrCat("RegExpPattern =",@TAB,sRegExpPattern,@LF,sMsgText,@LF) sMsgText = StrCat("SearchString =" ,@TAB,sSearchString ,@LF,sMsgText,@LF) sMsgTitle = "Demo udfRegExpFind (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, sMatchPropSep, sMatchItemSep)" IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :test3 ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Check e-mail address and separate it into three parts. sSearchString = "Please send mail to drag_on@x-yz-zy.com. Thanks!" sRegExpPattern = "([\w\-]+)@([\w\-]+)\.([\w\-]+)" ;sRegExpPattern = "([\w])+" ; Test it! ;bIgnoreCase = @FALSE ;bGlobalSearch = @FALSE ;bMultiLine = @FALSE bIgnoreCase = @TRUE bGlobalSearch = @TRUE bMultiLine = @FALSE sMatchPropSep = "|" sMatchListSep = @TAB sMatchList = udfRegExpMatch (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, bMultiLine, sMatchPropSep, sMatchListSep) iMatchCount = udfRegExpGetMatchCount (sMatchList, sMatchListSep) sMsgText = "" For iMatch=1 To iMatchCount sMatch = udfRegExpGetMatch (iMatch, sMatchList, sMatchListSep) sValue = udfRegExpGetMatchValue (sMatch, sMatchPropSep) iIndex = udfRegExpGetMatchIndex (sMatch, sMatchPropSep) iLength = udfRegExpGetMatchLength (sMatch, sMatchPropSep) sMsgText = StrCat(sMsgText,'Value' ,@TAB,' = ','"',sValue ,'"',@TAB) sMsgText = StrCat(sMsgText,'Index' ,@TAB,' = ','"',iIndex ,'"',@TAB) sMsgText = StrCat(sMsgText,'Length' ,@TAB,' = ','"',iLength,'"',@TAB) sMsgText = StrCat(sMsgText,@LF) iSubCount = udfRegExpGetSubMatchCount (sMatch, sMatchPropSep) For iSub=1 To iSubCount sSubMatch = udfRegExpGetSubMatchValue (iSub, sMatch, sMatchPropSep) sMsgText = StrCat(sMsgText,'SubMatch',iSub,@TAB,' = ','"',sSubMatch,'"',@LF) Next Next sMsgText = StrCat('GlobalSearch' ,@TAB,' = ','"',bGlobalSearch ,'"',@LF,@LF,sMsgText,@LF) sMsgText = StrCat('IgnoreCase' ,@TAB,' = ','"',bIgnoreCase ,'"',@LF,sMsgText,@LF) sMsgText = StrCat('RegExpPattern',@TAB,' = ','"',sRegExpPattern,'"',@LF,sMsgText,@LF) sMsgText = StrCat('SearchString' ,@TAB,' = ','"',sSearchString ,'"',@LF,sMsgText,@LF) sMsgTitle = "Demo udfRegExp (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch, sMatchPropSep, sMatchItemSep)" IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :test4 ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Replace one word with another word. sSearchString = "The quick brown fox jumped over the lazy dog." sRegExpPattern = "fox" sReplaceString = "cat" bIgnoreCase = @TRUE bGlobalSearch = @FALSE sReplacedString = udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch) sMsgTitle = "Demo udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)" sMsgText = "" sMsgText = StrCat(sMsgText,'SearchString' ,@TAB,' = ','"',sSearchString ,'"',@LF) sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',sRegExpPattern ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',sReplaceString ,'"',@LF) sMsgText = StrCat(sMsgText,'IgnoreCase' ,@TAB,' = ','"',bIgnoreCase ,'"',@LF) sMsgText = StrCat(sMsgText,'GlobalSearch' ,@TAB,' = ','"',bGlobalSearch ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',sReplacedString,'"',@LF) IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :test5 ;----------------------------------------------------------------------------------------------------------------------------------------------- ; In addition, the Replace method can replace subexpressions in the pattern. ; The following script swaps each pair of words in the original string sSearchString = "The quick brown fox jumped over the lazy dog." sRegExpPattern = "(\S+)(\s+)(\S+)" ; Swap pairs of words. sReplaceString = "$3$2$1" bIgnoreCase = @TRUE bGlobalSearch = @TRUE sReplacedString = udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch) sMsgTitle = "Demo udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)" sMsgText = "" sMsgText = StrCat(sMsgText,'SearchString' ,@TAB,' = ','"',sSearchString ,'"',@LF) sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',sRegExpPattern ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',sReplaceString ,'"',@LF) sMsgText = StrCat(sMsgText,'IgnoreCase' ,@TAB,' = ','"',bIgnoreCase ,'"',@LF) sMsgText = StrCat(sMsgText,'GlobalSearch' ,@TAB,' = ','"',bGlobalSearch ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',sReplacedString,'"',@LF) IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :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) IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) udfRegExpClose (objRegExp) EndIf ;----------------------------------------------------------------------------------------------------------------------------------------------- :test7 ;----------------------------------------------------------------------------------------------------------------------------------------------- ; Replace control character. sSearchString = StrCat("Control",@CR,"characters",@LF,"can also be indicated",@CR,@LF,"by RegExp pattern.",@CRLF) sRegExpPattern = "(\cM\cJ)|(\cJ)|(\cM)" ; @cr@lf or @lf or @cr sReplaceString = "<BR>" bIgnoreCase = @TRUE bGlobalSearch = @TRUE sReplacedString = udfRegExpReplace (sSearchString, sRegExpPattern, sReplaceString, bIgnoreCase, bGlobalSearch) sMsgTitle = "Demo udfRegExpReplace (sSearchString, sRegExpPattern, bIgnoreCase, bGlobalSearch)" sMsgText = "" sMsgText = StrCat(sMsgText,'SearchString' ,@TAB,' = ','"',sSearchString ,'"',@LF) sMsgText = StrCat(sMsgText,'RegExpPattern' ,@TAB,' = ','"',sRegExpPattern ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplaceString' ,@TAB,' = ','"',sReplaceString ,'"',@LF) sMsgText = StrCat(sMsgText,'IgnoreCase' ,@TAB,' = ','"',bIgnoreCase ,'"',@LF) sMsgText = StrCat(sMsgText,'GlobalSearch' ,@TAB,' = ','"',bGlobalSearch ,'"',@LF) sMsgText = StrCat(sMsgText,'ReplacedString',@TAB,' = ','"',sReplacedString,'"',@LF) IntControl (63,150,200,850,700) AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE) ;----------------------------------------------------------------------------------------------------------------------------------------------- :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 ^_ ;=============================================================================================================================================== ;*EOF*