Reputation:
I want to find the position of a substring by match index. To be precise, say there are 6 matches in a string and I want the position of match number 4. Example:
set "myString=barbarbarfoobarfoobarbar"
set "myMatch=bar"
set myMatchIndex=4
... do stuff ...
echo Position is: %position%
Position is: 13
Upvotes: 1
Views: 456
Reputation:
The following will produce the desired result.
Does not work with special characters such as (!) and ("), make sure to properly sanitize inputs.
:indexOf
setlocal ENABLEDELAYEDEXPANSION
set indexOf_StringPosition=0
set "indexOf_Var1=%~1"
set "indexOf_Var2=%~2"
set indexOf_Var3=%3
:indexOf_NoInitLabel
set indexOf_CurrentPosition=0
set "indexOf_StringTemp=!indexOf_Var1:*%indexOf_Var2%=!"
if "%indexOf_StringTemp%"=="%indexOf_Var1%" (
set indexOf_StringPosition=-1
goto :indexOf_BreakLabel
)
set "indexOf_StringTemp2=!indexOf_Var1:%indexOf_Var2%%indexOf_StringTemp%=!"
if "%indexOf_StringTemp2%"=="" (
set /a indexOf_CurrentPosition+=1
goto :indexOf_BreakLabel
)
:indexOf_LoopLabel
if "!indexOf_StringTemp2:~%indexOf_CurrentPosition%,1!"=="" (
set /a indexOf_CurrentPosition+=1
goto :indexOf_BreakLabel
)
set /a indexOf_CurrentPosition+=1
goto :indexOf_LoopLabel
:indexOf_BreakLabel
set /a indexOf_StringPosition+=%indexOf_CurrentPosition%
set /a indexOf_Var3-=1
set "indexOf_Var1=!indexOf_Var1:~%indexOf_CurrentPosition%!"
if "indexOf_Var1"=="" (
goto :indexOf_EndLabel
)
if "%indexOf_Var3%"=="0" (
goto :indexOf_EndLabel
)
goto :indexOf_NoInitLabel
:indexOf_EndLabel
(endlocal & set %4=%indexOf_StringPosition%)
goto :eof
indexOf can be called like so:
@echo off
set "myString=barbarbarfoobarfoobarbar"
set "myMatch=bar"
set myMatchIndex=4
call :indexOf "%myString%" "%myMatch%" %myMatchIndex% position
echo Position is: %position%
pause
rem Position is: 13
Important Note: The algorithm's index starts at 1. This means "b" is treated as 1, "a" is treated as 2, and so on. To start the index at 0, add the following after :indexOf_EndLabel
:
if not %indexOf_StringPosition%==-1 set /a indexOf_StringPosition-=1
Upvotes: 2