strimmer: a string trimmer

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
Sponge Belly
Posts: 216
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

strimmer: a string trimmer

#1 Post by Sponge Belly » 03 Aug 2013 16:20

Hi All! :-)

Below is an alternative technique for trimming leading and trailing spaces and tabs from a string…

Edit: Please read revised code.

- SB
Last edited by Sponge Belly on 13 Nov 2017 09:36, edited 1 time in total.

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: strimmer: a string trimmer

#2 Post by penpen » 06 Aug 2013 16:19

The use of the Escape and Backspace character prevents from trimming:

Code: Select all

for /f "delims=rem " %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
for /f "delims=rem " %%a in ('"prompt $E&for %%b in (1) do rem"') do set "ESC=%%a"
set "val7= %BS%  abc  %BS% "
set "val8= %ESC%  abc  %ESC%  "
The output then is:

Code: Select all

7:  abc  ]
8:[  abc  ]

penpen

Edit: Sorry the example was bad as it worked as expected, i have corrected it.
Last edited by penpen on 07 Aug 2013 13:07, edited 1 time in total.

Sponge Belly
Posts: 216
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: strimmer: a string trimmer

#3 Post by Sponge Belly » 07 Aug 2013 09:15

Thanks Penpen…

Edit: Please read revised code.

- SB
Last edited by Sponge Belly on 13 Nov 2017 09:39, edited 2 times in total.

jeb
Expert
Posts: 1041
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: strimmer: a string trimmer

#4 Post by jeb » 08 Aug 2013 02:31

Hi Sponge Belly,

Sponge Belly wrote:Btw, is it necessary to double all quotes only to put them all back the way they were the line after next? I don’t follow that step. :?:
Sponge Belly wrote:set "str=!str:"=""!"
if not defined nodelay set "str=%str:!=^^^!%" !
set "str=!str:""="!"

Yes it's necessary, as it avoids problems with unquoted special characters.

You can test it with a string like "&"&

set "str=&"^&"

This would fail when expanding with set "str=%str:!=^^^!%" ! as it results to
set "str=&"&" !

By doubling all quotes, all parts of the strings are inside quotes.

jeb

Sponge Belly
Posts: 216
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: strimmer: a string trimmer

#5 Post by Sponge Belly » 10 Aug 2013 15:50

Thanks for the explanation, Jeb! :-)

- SB
Last edited by Sponge Belly on 13 Nov 2017 09:40, edited 1 time in total.

Sponge Belly
Posts: 216
Joined: 01 Oct 2012 13:32
Location: Ireland
Contact:

Re: strimmer: a string trimmer

#6 Post by Sponge Belly » 13 Nov 2017 09:27

Hello Again! :)

Wow, I can’t believe this topic is over 4 years old! :shock:

What an enthusiastic little puppy I was in those days… :roll:

Anyways, I’ve revised the code for my string strimmer. It is now completely expansion-insensitive and exploits the option to omit the closing quote in the last parameter of CALL to trim trailing whitespace. It’s also a lot simpler—a sure sign of improvement! ;)

Code: Select all

@echo off & setlocal enableextensions disabledelayedexpansion
(set lf=^
%= BLANK LINE REQUIRED =%
)
set "cr=" & if not defined cr for /f "skip=1" %%C in (
'echo(^|replace ? . /w /u'
) do set "cr=%%C"

set ^"orig=  !random!  !  ^^!  ^^^^!  ^"^^  ^&^"^&  ^^^" %%os%%  ^"

call :strim res1 orig

setlocal enabledelayedexpansion
call :strim res2 orig
echo(orig: [!orig!]
echo(res1: [!res1!]
echo(res2: [!res2!]
endlocal

endlocal & goto :EOF

:strim result= original=
:: trims leading and trailing whitespace from a string
setlocal
set "ddx=!"
setlocal enabledelayedexpansion
set "die=" & if not defined %2 (>&2 echo(var "%2" not defined
set "die=1") else set "str=!%2!"

if not defined die for %%L in ("!lf!") ^
do if "!str!" neq "!str:%%~L=!" (
>&2 echo(var "%2" contains linefeeds & set "die=1")

if not defined die for %%C in ("!cr!") ^
do if "!str!" neq "!str:%%~C=!" (
>&2 echo(var "%2" contains carriage returns & set "die=1")

if not defined die (for /f eol^= %%A in ("!str!") do rem nop
) || (>&2 echo(var "%2" consists entirely of whitespace
set "die=1")

if defined die goto die

set "str=!str:^=^^^^!"
set "str=!str:"=""!"
set "str=%str:!=^^^!%" !

call :_strim "%%str%%

if not defined ddx set "str=!str:^=^^^^!"
if not defined ddx set "str=%str:!=^^^!%" !
set "str=!str:""="!"

for /f tokens^=*^ eol^= %%A in ("!str!") do (
endlocal & endlocal & set "%1=%%A" !)
exit /b 0

:die
endlocal & endlocal & set "%1=" & exit /b 1

:_strim
:: subfunction
set "str=%~1" !
exit /b 0
Thanks to Jeb for his awesome safe return technique and Dave Benham’s tip on how to avoid caret-doubling when using CALL.

- SB

Post Reply