For the sample string you provided, Stephan's approach is perfectly sufficient.
However, if the string contains token separators (white-spaces, ,
, ;
, =
), quotation marks ("
), wild-cards (*
, ?
) or other special characters (^
, &
, (
, )
, >
, <
, |
) it might probably fail. You could of course replace most of such characters by others in advance, and use delayed expansion rather than immediate one, but this still does not resolve all issues (for instance, you cannot replace all =
or *
characters due to the sub-string replacement syntax).
The following approach however can deal with every arbitrary combination of all such characters. Basically it replaces every period (.
) with a new-line (line-feed) character and lets find /C /V ""
count the total number of lines.
@echo off
set "string=17.09.01.04.03"
setlocal EnableDelayedExpansion
if defined string (set ^"strtmp=!string:.=^
%= empty string =%
!^") else set "strtmp="
for /F %%C in ('cmd /V /C echo(^^!strtmp^^!^| find /C /V ""') do set /A "count=%%C-1"
echo "!string!" contains %count% periods.
endlocal
The periods become replaced by line-feeds in advance, using delayed expansion in order not to fail if any special characters occur. The for /F
loop executes the command line cmd /V /C echo(^^!string^^!| find /C /V ""
and captures its output in a variable, reduced by one as find /C /V ""
actually returns the number of lines, which are separated by one less line-feeds (hence periods), originally. The double-escaped exclamation marks ^^!
are needed in order to ensure that the variable strtmp
is actually expanded within the explicitly invoked inner-most cmd
instance, because otherwise, the contained multi-line string is not correctly transported into the pipe (|
).