udfStrRegExpSplitEx
str udfStrRegExpSplitEx (str, str, int, int, str)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfStrRegExpSplitEx (strString, strRegExpPattern, intSplitCount, intStartAt, strDelimiter) ; intStartAt is one based.
If strString == "" Then Return ""
If intSplitCount == 1 Then Return strString

objRegExp = ObjectCreate ("VBScript.RegExp")
objRegExp.Pattern = strRegExpPattern : "|$"
objRegExp.IgnoreCase = @FALSE
objRegExp.Global = @TRUE
objRegExp.MultiLine = @FALSE
objMatches = objRegExp.Execute(strString)

intSplitCount = Max (0, Min (intSplitCount, objMatches.count))
If intSplitCount == 0 Then intSplitCount = objMatches.count
If intSplitCount == 1 Then Return strString
intStartAt = Max (1, Min (intStartAt, 1 + StrLen (strString)))
intSplitLast = objMatches.count - 1
strList = ""

intSplit = 0
objMatch = objMatches.item(intSplit)
intPos = objMatch.FirstIndex + 1
While intStartAt > intPos
   intSplit = intSplit + 1
   objMatch = objMatches.item(intSplit)
   intPos = objMatch.FirstIndex + 1
EndWhile
strList = StrSub (strString, 1, objMatch.FirstIndex)
ForEach objSubMatch In objMatch.SubMatches
   If objSubMatch != "" Then strList = strList : strDelimiter : objSubMatch
Next
intSplitCount = intSplitCount - 1

intPosPrev = objMatch.FirstIndex + 1 + objMatch.Length
If intSplitCount > 1
   While intSplit < intSplitLast
      intSplit = intSplit + 1
      objMatch = objMatches.item(intSplit)
      intPos = objMatch.FirstIndex + 1
      strList = strList : strDelimiter : StrSub (strString, intPosPrev, intPos - intPosPrev)
      ForEach objSubMatch In objMatch.SubMatches
         If objSubMatch != "" Then strList = strList : strDelimiter : objSubMatch
      Next
      intPosPrev = intPos + objMatch.Length
      intSplitCount = intSplitCount - 1
      If intSplitCount < 2 Then Break
   EndWhile
EndIf

If intSplit < intSplitLast Then strList = strList : strDelimiter : StrSub (strString, intPosPrev, -1)

If !objMatches.item(0).length Then If intStartAt < 2 Then Return StrSub (strList, 2, -1) ; Workaround against empty match at start of string.
Return strList
;..........................................................................................................................................
; This UDF udfStrRegExpSplitEx mimics the behaviour of the .NET Framework Class Library Regex.Split Method (String, Int32, Int32).
; The function splits the specified input string (strString) a specified maximum number of times (intSplitCount)
; at the positions defined by a regular expression (strRegexPattern).
; The search for the regular expression pattern starts at a specified character position intStartAt in the input string.
; The result is a string list of matches and possibly submatches separated by any useful string (strDelimiter).
;
; Detlev Dalitz.20090623.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------

If Param0 Then If Param1 == ".." Then Return ; Leave this script here when called by another script with the specified parameter.


; Test.

strDelimiter = @LF

:Test1
strString1 = "plum-pear"
strRegExpPattern1 = "-"
strSplitList1 = udfStrRegExpSplitEx (strString1, strRegexpPattern1, 0, 0, strDelimiter)
arrA1 = Arrayize (strSplitList1, strDelimiter)
;   "plum"
;   "pear"
BreakPoint

strString2 = "plum-pear"
strRegExpPattern2 = "(-)"
strSplitList2 = udfStrRegExpSplitEx (strString2, strRegexpPattern2, 0, 0, strDelimiter)
arrA2 = Arrayize (strSplitList2, strDelimiter)
;   "plum"
;   "-"
;   "pear"
BreakPoint

:Test3
strString3 = "-plum--pear-"
strRegExpPattern3 = "-"
strSplitList3 = udfStrRegExpSplitEx (strString3, strRegexpPattern3, 0, 0, strDelimiter)
arrA3 = Arrayize (strSplitList3, strDelimiter)
;   ""
;   "plum"
;   ""
;   "pear"
;   ""
BreakPoint

:Test4
strString4 = "07/14/2007"
strRegExpPattern4 = "(-)|(/)"
strSplitList4 = udfStrRegExpSplitEx (strString4, strRegexpPattern4, 0, 0, strDelimiter)
arrA4 = Arrayize (strSplitList4, strDelimiter)
;   "07"
;   "/"
;   "14"
;   "/"
;   "2007"
BreakPoint

:Test5
strString5 = "characters"
strRegExpPattern5 = ""
strSplitList5 = udfStrRegExpSplitEx (strString5, strRegexpPattern5, 0, 0, strDelimiter)
arrA5 = Arrayize (strSplitList5, strDelimiter)
;   "c"
;   "h"
;   "a"
;   "r"
;   "a"
;   "c"
;   "t"
;   "e"
;   "r"
;   "s"
BreakPoint

:Test6
strString6 = "characters"
strRegExpPattern6 = "#"
strSplitList6 = udfStrRegExpSplitEx (strString6, strRegexpPattern6, 0, 0, strDelimiter)
arrA6 = Arrayize (strSplitList6, strDelimiter)
;   "characters"
BreakPoint

:Test7
strString7 = ""
strRegExpPattern7 = ""
strSplitList7 = udfStrRegExpSplitEx (strString7, strRegexpPattern7, 0, 0, strDelimiter)
arrA7 = Arrayize (strSplitList7, strDelimiter)
;   ""
BreakPoint

:Test8
strString8 = "apple-apricot-plum-pear-pomegranate-pineapple-peach"
strRegExpPattern8 = "-"
strSplitList8 = udfStrRegExpSplitEx (strString8, strRegexpPattern8, 4, 16, strDelimiter)
arrA8 = Arrayize (strSplitList8, strDelimiter)
;   "apple-apricot-plum"
;   "pear"
;   "pomegranate"
;   "pineapple-peach"
BreakPoint

:Test9
strString9 = "characters"
strRegExpPattern9 = ""
strSplitList9 = udfStrRegExpSplitEx (strString9, strRegexpPattern9, 4, 5, strDelimiter)
arrA9 = Arrayize (strSplitList9, strDelimiter)
;   "char"
;   "a"
;   "c"
;   "ters"
BreakPoint

Exit