This is much more useful
I altered the output slightly:
. . .
I am posting the script with those changes in its entirety, with just a little more added function. I added an x3 variable to the magic incantation to save the last position found and used that to set the return code (with a value of -1 if not found). Edited 12/23/2017: return code is actually negative the length of the search string if not found(correction).
So, here is StrPos.bat:
Code: Select all
:StrPos Delim String
Rem Start http://www.dostips.com/forum/viewtopic.php?p=54609#p54609
set /A "rc=-1"
if not defined x echo/& echo No string& exit /B %rc%
if not defined v echo/& echo No delimiter& exit /B %rc%
call :strLen v k=
set /A i=-k
set "w=!x:%~1=" ^& call :strLen w j ^& set /A i+=j+k ^& set "x2=¡x2¡,¡i¡" ^& set "w=!"
if defined x2 (
set /A "rc=%i%"
echo Substring "%~1" at positions: %x2%
echo Last position: %i%
exit /B %rc%
:strLen var len=
for /L %%a in (8,-1,0) do (
set /A "newLen=%2+(1<<%%a)"
for %%b in (!newLen!) do if "!str:~%%b,1!" neq "" set "%2=%%b"
for %%a in (!%2!) do endlocal & set "%2=%%a"
This kind of return code seems easy enough to manage, but is it good form? Would two 16bit numbers be better? Something like 0x00000004 for success with 4 and 0x00010000 for failure.
Anyway, as an interesting side effect one could use
to set ERRORLEVEL to 5.
Edited 11/23/2017: x3 eliminated to use i directly, as suggest by Antonio.
Edited 12/23/2017: Usage comment and return code clarification(correction).
Edit: Usage limitation. Because of the nature of the substitutions, only the first in a set of overlapping source strings is found in the target string. For example,
Code: Select all
StrPos "aa123aa" "bbbaa123aa123aaccc"
will not find the second occurrence of "aa123aa"..