;========================================================================================================================================== ; How to trim a text line? ; ; How to remove space characters at one side of a string? ; ; Comparison of methods for trimming single lines and trimming multiple lines. ; ; Detlev Dalitz.20020130.20040404.20100208. ;========================================================================================================================================== ;---; ; 1 ; ;---+-------------------------------------------------------------------------------------------------------------------------------------- ; ; WinBatch provides the function StrTrim(). ; ; strTrimmed = strTrim (" 1 2 3 test ") ; Will give the result "1 2 3 test". ; ; The WinBatch function strTrim () removes spaces and tab characters from the beginning and end of a text string. ; ;------------------------------------------------------------------------------------------------------------------------------------------ ;---; ; 2 ; ;---+-------------------------------------------------------------------------------------------------------------------------------------- ; ; What can we do in such cases when trimming is needed only at one side of the string? ; ;------------------------------------------------------------------------------------------------------------------------------------------ ; ; Once we have found out a method to prevent the input string of trimming at one edge (saving the other edge), ; we are able to use the WinBatch native function StrTrim (). ; ; We can hinder StrTrim () to trim both sides of a string, if we enclose the input string with a character, ; which StrTrim () cannot detect as trimmable. ; To prevent the right edge from trimming we can add a blocker character at the right edge. ; To prevent the left edge from trimming we can add a blocker character at the left edge. ; ; Example for left trimming: ; strString = " 1 2 3 test " ; This is the original string of 16 character size. ; strString = strString : @LF ; Just of oddity we add the ASCII 10 LineFeed character. ; strString = strTrim (strString) ; This will give the result "1 2 3 test @LF", this is left trimmed. ; strString = ItemRemove (-1, strString, @LF) ; To get the final result we have to cut away the trailing ; ; trim preventing character, which will give the result "1 2 3 test ". ; ; Example for right trimming: ; strString = " 1 2 3 test " ; This is the original string of 16 character size. ; strString = @LF : strString ; Just of oddity we add the ASCII 10 LineFeed character. ; strString = strTrim (strString) ; This Will give the result "@LF 1 2 3 test", this is right trimmed. ; strString = ItemRemove (1, strString, @LF) ; To get the final result we have to cut away the leading ; ; trim preventing character, which will give the result " 1 2 3 test". ;------------------------------------------------------------------------------------------------------------------------------------------ ;---; ; 3 ; ;---+-------------------------------------------------------------------------------------------------------------------------------------- ; User defined functions for trimming a single line. ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimLeftV1 (strString) Return ItemRemove (-1, StrTrim (strString : @LF), @LF) #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimRightV1 (strString) Return ItemRemove (1, StrTrim (@LF : strString), @LF) #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;---; ; 4 ; ;---+-------------------------------------------------------------------------------------------------------------------------------------- ; User defined functions for trimming multiple lines with EOL sequence @CRLF (Note: must be @CRLF). ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimLeftV2 (strString) If strString == "" Then Return strString intBBSize = 1 + StrLen (strString) hdlBB = BinaryAlloc (intBBSize) BinaryEodSet (hdlBB, intBBSize) BinaryPokeStr (hdlBB, 0, @LF) BinaryPokeStr (hdlBB, 1, strString) strSrch = @LF : " " While !!BinaryReplace (hdlBB, strSrch, @LF, @TRUE) EndWhile strString = BinaryPeekStr (hdlBB, 1, BinaryEodGet (hdlBB) - 1) hdlBB = BinaryFree (hdlBB) Return strString #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimRightV2 (strString) If strString == "" Then Return strString intBBSize = 1 + StrLen (strString) hdlBB = BinaryAlloc (intBBSize) BinaryEodSet (hdlBB, intBBSize) BinaryPokeStr (hdlBB, intBBSize - 1, @CR) BinaryPokeStr (hdlBB, 0, strString) strSrch = " " : @CR While !!BinaryReplace (hdlBB, strSrch, @CR, @TRUE) EndWhile strString = BinaryPeekStr (hdlBB, 0, BinaryEodGet (hdlBB) - 1) hdlBB = BinaryFree (hdlBB) Return strString #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimLeftV3 (strString) If strString == "" Then Return strString strString = @LF : strString strSrch = @LF : " " While !!StrIndex (strString, strSrch, 0, @FWDSCAN) strString = StrReplace (strString, strSrch, @LF) EndWhile Return StrSub (strString, 2, -1) #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfStrTrimRightV3 (strString) If strString == "" Then Return strString strString = strString : @CR strSrch = " " : @CR While !!StrIndex (strString, strSrch, 0, @FWDSCAN) strString = StrReplace (strString, strSrch, @CR) EndWhile Return StrSub (strString, 1, StrLen (strString) - 1) #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ ; Functional Test. strIn = " 1 2 3 test " strOut = udfStrTrimLeftV1 (strIn) strMsgTitle = "Demo udfStrTrimLeftV1 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) strOut = udfStrTrimRightV1 (strIn) strMsgTitle = "Demo udfStrTrimRightV1 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) strOut = udfStrTrimLeftV2 (strIn) strMsgTitle = "Demo udfStrTrimLeftV2 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) strOut = udfStrTrimRightV2 (strIn) strMsgTitle = "Demo udfStrTrimRightV2 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) strOut = udfStrTrimLeftV3 (strIn) strMsgTitle = "Demo udfStrTrimLeftV3 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) strOut = udfStrTrimRightV3 (strIn) strMsgTitle = "Demo udfStrTrimRightV3 (strString)" strMsgText = 'strIn' : @TAB : '= "' : strIn : '"' : @CRLF : 'strOut' : @TAB : '= "' : strOut : '"' Pause (strMsgTitle, strMsgText) ;------------------------------------------------------------------------------------------------------------------------------------------ ; Performance Test. strIn = StrFill (" ", 20) : "Performance Test" : StrFill (" ", 20) intLen = StrLen (strIn) + StrLen (@CRLF) strIn2 = StrFill (strIn : @CRLF, 100 * intLen) strIn3 = strIn2 intTestLoop = 100 intTestMin = 2 intTestMax = 3 ClipPut ("") :StrTrimLeft ClipAppend (@CRLF : "udfStrTrimLeft" : @CRLF) strMsgTitle = "Demo udfStrTrimLeft (strString) Performance Test" For intT = intTestMin To intTestMax Display (1, strMsgTitle, "Running Test StrTrimLeft %intT%, please wait ...") Exclusive (@ON) intTicksStart = GetTickCount () For intL = 1 To intTestLoop strOut%intT% = udfStrTrimLeftV%intT% (strIn%intT%) Next intTicks%intT% = GetTickCount () - intTicksStart Exclusive (@OFF) Display (2, strMsgTitle, "StrLen (strIn) = " : StrLen (strIn%intT%) : @LF : "StrLen (strOut) = " : StrLen (strOut%intT%)) Next intTicksMax = 0 For intT = intTestMin To intTestMax intTicksMax = Max (1, intTicksMax, intTicks%intT%) Next For intT = intTestMin To intTestMax intPct%intT% = 100 * intTicks%intT% / intTicksMax Next strMsgText = "" For intT = intTestMin To intTestMax strMsgText = strMsgText : "Test " : intT : @TAB : "Ticks = " : @TAB : intTicks%intT% : @TAB : "Pct = " : @TAB : intPct%intT% : " %%" : @CRLF Next Pause (strMsgTitle, strMsgText) ClipAppend (strMsgText) :StrTrimRight ClipAppend (@CRLF : "udfStrTrimRight" : @CRLF) strMsgTitle = "Demo udfStrTrimRight (strString) Performance Test" For intT = intTestMin To intTestMax Display (1, strMsgTitle, "Running Test StrTrimRight %intT%, please wait ...") Exclusive (@ON) intTicksStart = GetTickCount () For intL = 1 To intTestLoop strOut%intT% = udfStrTrimRightV%intT% (strIn%intT%) Next intTicks%intT% = GetTickCount () - intTicksStart Exclusive (@OFF) Display (2, strMsgTitle, "StrLen (strIn) = " : StrLen (strIn%intT%) : @LF : "StrLen (strOut) = " : StrLen (strOut%intT%)) Next intTicksMax = 0 For intT = intTestMin To intTestMax intTicksMax = Max (1, intTicksMax, intTicks%intT%) Next For intT = intTestMin To intTestMax intPct%intT% = 100 * intTicks%intT% / intTicksMax Next strMsgText = "" For intT = intTestMin To intTestMax strMsgText = strMsgText : "Test " : intT : @TAB : "Ticks = " : @TAB : intTicks%intT% : @TAB : "Pct = " : @TAB : intPct%intT% : " %%" : @CRLF Next Pause (strMsgTitle, strMsgText) ClipAppend (strMsgText) :CANCEL Exit ; udfStrTrimLeft ; Test 2 Ticks = 703 Pct = 48 % Binary Replace. ; Test 3 Ticks = 1453 Pct = 100 % String Replace. ; ; udfStrTrimRight ; Test 2 Ticks = 719 Pct = 47 % Binary Replace. ; Test 3 Ticks = 1515 Pct = 100 % String Replace.