In a batch file I arrive at a string of form \w (_p\d )* ie.
something
some_text_p1
other_txt_p25
What I want now is to remove the (_p\d ) suffix if it exists. Any chance to do something like that in a batch file?
I've found https://www.dostips.com/DtTipsStringManipulation.php but I don't see any regex stuff around there. I'm not actually interested in using regex, I simply want that suffix to be removed by any means.
CodePudding user response:
@ECHO Off
SETLOCAL
:: submit strings for testing
FOR %%b IN (something some_text_p1 other_txt_p25 "more text_p66" 96 p77 _p03) DO CALL :test "%%~b"&CALL :test2 "%%~b"
GOTO :EOF
:test
SET "teststring=%~1"
CALL :rem_pds %teststring:_= %
ECHO Testing: "%teststring%" Result: "%resultstring%"
GOTO :eof
:test2
SET "teststring=%~1"
SET "resultstring=%teststring%"
:test2lp
IF NOT DEFINED resultstring SET "resultstring=%teststring%"&GOTO t2done
IF "%resultstring:~-1%" geq "0" IF "%resultstring:~-1%" leq "9" SET "resultstring=%resultstring:~0,-1%"&GOTO test2lp
IF /i "%resultstring:~-2%" equ "_p" (SET "resultstring=%resultstring:~0,-2%") ELSE SET "resultstring=%teststring%"
:t2done
ECHO Testing2: "%teststring%" Result: "%resultstring%"
GOTO :eof
:rem_pds
SET "resultstring=%1"
IF "%2" neq "" shift&GOTO rem_pds
:: resultstring has last token
IF /i "%resultstring:~0,1%" neq "P" goto nochange
:: ? Must digit string exist ? if yes, then no change
IF /i "%1"=="P" GOTO nochange
SET "resultstring=9%resultstring:~1%"
FOR /l %%z IN (0,1,9) DO CALL SET "resultstring=%%resultstring:%%z=%%"
IF DEFINED resultstring GOTO nochange
SET "resultstring=%1"
SET /a resultlength=1
:resultll
SET /a resultlength =1
SET "resultstring=%resultstring:~1%"
IF DEFINED resultstring GOTO resultll
FOR %%z IN (%resultlength%) DO CALL SET "resultstring=%%teststring:~-%%z%%"
IF "%resultstring:~0,1%" neq "_" GOTO nochange
FOR %%z IN (%resultlength%) DO CALL SET "resultstring=%%teststring:~0,-%%z%%"
GOTO :eof
:nochange
SET "resultstring=%teststring%"
GOTO :eof
:rem_pds
is the main meat of the routine - the part before is simply setting up an easy testing framework.
rem_pds
receives the teststring with all _
transformed to spaces and simply shifts the tokens until the second is empty, leaving p\d
in %1
.
If the first character is not p
then no change is required.
Otherwise, append 9
to the string after the p
, then remove all digits from the result. Since 9
is the last to be removed, resultstring
will not be empty when %%z
is 9
...
If the result is not empty, then there's some other character where we're trying to locate digits, so no change is required.
Next, calculate the length of the _p\d
by successively removing the last character from the last-provided token and counting. Start the count at 1
because we want to include one extra character - the underscore.
Pick out the character before the p\d
string; if it's an underscore, grab the part before the underscore by position, otherwise no change.
--- on the other hand, I prefer :test2
.
CodePudding user response:
If all you wanted to do was to remove any underscore leading suffix, and refuse to use more appropriate tools, this may be all you require.
@Set "String=one_two_three_four_five_six_789"
@Set "Prefix=%String:_="&:"%"
@SetLocal EnableDelayedExpansion
@Set "Suffix="
@Set "String=%String:_=" & Set "Prefix=!Prefix!!Suffix!" & Set "Suffix=_%"
@EndLocal & Set "Prefix=%Prefix%"
@Set Prefix
@Pause
You could of course use it as a called label:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
For %%G In (
"something"
"some_text_p1"
"other_txt_p25"
"one_two_three_four_five_six_789"
) Do Call :Func %%G
Pause
GoTo :EOF
:Func
Set "String=%~1"
Set "Prefix=%String:_="&:"%"
SetLocal EnableDelayedExpansion
Set "Suffix="
Set "String=%String:_=" & Set "Prefix=!Prefix!!Suffix!" & Set "Suffix=_%"
EndLocal & Set "Prefix=%Prefix%"
Set Prefix
Exit /B