How to split string without for loop in batch file

CrazyCoder picture CrazyCoder · Jan 31, 2013 · Viewed 36.9k times · Source

I want to split a string in two parts, without using any for loop.

For example, I have the string in a variable:

str=45:abc

I want to get 45 in a variable and abc in another variable. Is it possible in batch file?

pattern is like somenumber:somestring

Answer

jeb picture jeb · Jan 31, 2013

You could split the str with different ways.

The for loop, you don't want use it.

The trailing part is easy with the * (match anything until ...)
set "var2=%str:*:=%"

The leading part can be done with a nasty trick
set "var1=%str::="^&REM #%

The caret is needed to escape the ampersand,
so effectivly the colon will be replaced by "&REM # So in your case you got the line after replacing
set "var1=4567"&REM #abcde
And this is splitted into two commands

set "var1=4567"
REM #abcde` 

And the complete code is here:

set "str=4567:abcde"
echo %str%
set "var1=%str::="^&REM #%
set "var2=%str:*:=%"
echo var1=%var1% var2=%var2%

Edit 2: More stable leading part

Thanks Dave for the idea to use a linefeed.
The REM technic isn't very stable against content with quotes and special characters.
But with a linefeed trick there exists a more stable version which also works when the split argument is longer than a single character.

@echo off
setlocal enableDelayedExpansion
set ^"str=456789#$#abc"
for /F "delims=" %%a in (^"!str:#$#^=^

!^") do (
  set "lead=%%a"
  goto :break
)
:break
echo !lead!

Solution 3: Adpated dbenhams answer

Dbenham uses in his solution a linefeed with a pipe.
This seems a bit over complicated.
As the solution uses the fact, that the parser removes the rest of the line after an unescaped linefeed (when this is found before or in the special character phase).

At first the colon character is replaced to a linefeed with delayed expansion replacement.
That is allowed and the linefeed is now part of the variable.
Then the line set lead=%lead% strips the trailing part.
It's better not to use the extended syntax here, as set "lead=%lead%" would break if a quote is part of the string.

setlocal enableDelayedExpansion
set "str=45:abc"
set ^"lead=!str::=^

!"
set lead=%lead%
echo "!lead!"