I recently discovered an interesting trick that allows to split a string based on a delimiter without using for
command, so I couldn't resist the temptation to post it here. This question also represent a different way to use my method (split string in more than 2 different variables). Here it is:
@echo off
setlocal EnableDelayedExpansion
set /p "ReleaseVersion=Please specify the software release version : "
set "v=Minor"
set "Major=%ReleaseVersion:.=" & (if defined Minor set v=Revision) & set "!v!=%"
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%
Further details at this post.
EDIT: Some explanations added
You may read a full description of the split method here. However, this answer also use an if defined Minor
command in order to change the variable name from "Minor" to "Revision" after Minor variable value was set; this point can be easily understood if you remove the @echo off
command and review the trace output.
Although this method allows to define more than two variables with different names, it is somewhat cumbersome to insert a & (if defined prevVar set v=newVar)
command for each additional variable. For example:
@echo off
setlocal EnableDelayedExpansion
set "str=1.0.2.25"
set "v=Minor"
set "Major=%str:.=" & (if defined Minor set v=Revision) & (if defined Revision set v=Subrev) & set "!v!=%"
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
The splitting of a string in several different variables can the achieved in a better way with the aid of a subroutine:
@echo off
setlocal EnableDelayedExpansion
call :SplitString "1.0.2.35" Major Minor Revision Subrev
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
goto :EOF
:SplitString string varName ...
rem Get string in "str" variable
set "str=%~1"
rem Create "v" array with variable names
set i=0
for %%a in (%*) do (
set "v[!i!]=%%a"
set /A i+=1
)
rem Separate the string in individual variables
set "p=%%"
set i=1
set "!v[1]!=%str:.=" & set /A i+=1 & call set "!p!v[!i!]!p!=%"
exit /B
The split method used in this subroutine is explained with detail in this post, but I copied here the relevant parts and modified they for this example:
Note that the call set "!p!v[!i!]!p!=%"
part is a nested replacement that is executed with each one of the substrings of the original replacement. This way, this method is comprised of three stages:
- The original string is split in several parts via the first %str% expansion, for example:
call set "!p!v[!i!]!p!=1"
, call set "!p!v[!i!]!p!=0"
, etc.
- Each part is processed using delayed expansion !variables! to assemble the final expression. This method allows to insert quotes and other special characters, like percent signs, in places that the original %expansion% can not handle. For example:
call set "%v[1]%=1"
, call set "%v[2]%=0"
, etc.
- The final expression in each part is evaluated via the nested CALL command, for example:
set "Major=1"
, set "Minor=0"
, etc.
EDIT 2018/02/18: New method added
I developed a new method that allows to assign values to different variables using just one line. This method is new in the sense that allows to split two variables in the same line/replacement:
@echo off
setlocal EnableDelayedExpansion
set "str=1.0.2.25"
set "vars=Major Minor Revision Subrev"
set "p=%%"
set "v=%vars: =" & set "s=!str:*.=!" & call set "!v!=!p!str:.!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!=!s!"
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
EDIT 2022/01/05: New simpler method added
I developed a new method to achieve this split that is simpler in the sense that it does not introduce additional elements besides the variable names:
@echo off
setlocal
set "str=1.0.2.25"
set "Major=%str:.=" & set /A "Minor=Revision, Revision=Subrev, Subrev=%"
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
In this example an even simpler set /A
command is used. If the assigned values were not numeric, just change the single SET /A by three standard set
commands.