我需要在 Windows 批处理脚本中实现一个函数,以将 LastIndexOf 字符转换为给定的字符串。
例如:给定以下字符串,我需要获取字符的最后一个索引'/'
:
/name1/name2/name3
^
所以我需要获得价值:
12
我需要在 Windows 批处理脚本中实现一个函数,以将 LastIndexOf 字符转换为给定的字符串。
例如:给定以下字符串,我需要获取字符的最后一个索引'/'
:
/name1/name2/name3
^
所以我需要获得价值:
12
Joey 的解决方案有效,但要查找的字符是硬编码的,而且速度相对较慢。
这是一个快速的参数化函数,可以在字符串中找到任何字符(nul 除外)。我传递包含字符串和字符的变量名而不是字符串文字,以便函数轻松支持所有字符。
@echo off
setlocal
set "test=/name1/name2/name3"
set "char=/"
::1st test simply prints the result
call :lastIndexOf test char
::2nd test stores the result in a variable
call :lastIndexOf test char rtn
echo rtn=%rtn%
exit /b
:lastIndexOf strVar charVar [rtnVar]
setlocal enableDelayedExpansion
:: Get the string values
set "lastIndexOf.char=!%~2!"
set "str=!%~1!"
set "chr=!lastIndexOf.char:~0,1!"
:: Determine the length of str - adapted from function found at:
:: http://www.dostips.com/DtCodeCmdLib.php#Function.strLen
set "str2=.!str!"
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str2:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
:: Find the last occurrance of chr in str
for /l %%N in (%len% -1 0) do if "!str:~%%N,1!" equ "!chr!" (
set rtn=%%N
goto :break
)
set rtn=-1
:break - Return the result if 3rd arg specified, else print the result
( endlocal
if "%~3" neq "" (set %~3=%rtn%) else echo %rtn%
)
exit /b
创建一个更通用的:indexOf
函数不需要太多修改,该函数需要一个额外的参数来指定要查找的事件。负数可以指定反向搜索。所以 1 可能是第一个,2 是第二个,-1 最后一个,-2 倒数第二个,等等。
(注意:我假设是 Windows 批处理文件,因为坦率地说,到目前为止,我只看到一个问题询问实际的DOS 批处理文件。大多数人只是将“DOS”错误地归因于任何具有灰色窗口的东西——黑色等宽文本,不知道他们实际上在说什么。)
只需遍历它,随时更新索引:
@echo off
setlocal enabledelayedexpansion
set S=/name1/name2/name3
set I=0
set L=-1
:l
if "!S:~%I%,1!"=="" goto ld
if "!S:~%I%,1!"=="/" set L=%I%
set /a I+=1
goto l
:ld
echo %L%
我知道这个问题现在有点老了,但我需要一个函数来找到字符串中子字符串(任意长度)的位置,并根据我的目的调整 dbenham 的解决方案。此功能还适用于字符串中的单个字符,如原始问题中所要求的那样,并且可以搜索特定实例(如 dbenham 所建议的那样)。
要使用此函数,必须传递实际的字符串。Dbenham 确实注意到,与传递实际变量相比,它支持的字符更少,但我发现这种变体更可重用(尤其是使用管道)。
第三个参数采用应该找到的实例,负数指定从末尾开始搜索。返回的索引是从字符串开头到子字符串中第一个字符的偏移量。
@ECHO off
SET search_string=sub
CALL :strIndex "The testing subjects subjects to testing." "%search_string%" -2
ECHO %ERRORLEVEL%
PAUSE
EXIT
:strIndex string substring [instance]
REM Using adaptation of strLen function found at http://www.dostips.com/DtCodeCmdLib.php#Function.strLen
SETLOCAL ENABLEDELAYEDEXPANSION
SETLOCAL ENABLEEXTENSIONS
IF "%~2" EQU "" SET Index=-1 & GOTO strIndex_end
IF "%~3" EQU "" (SET Instance=1) ELSE (SET Instance=%~3)
SET Index=-1
SET String=%~1
SET "str=A%~1"
SET "String_Length=0"
FOR /L %%A IN (12,-1,0) DO (
SET /a "String_Length|=1<<%%A"
FOR %%B IN (!String_Length!) DO IF "!str:~%%B,1!"=="" SET /a "String_Length&=~1<<%%A"
)
SET "sub=A%~2"
SET "Substring_Length=0"
FOR /L %%A IN (12,-1,0) DO (
SET /a "Substring_Length|=1<<%%A"
FOR %%B IN (!Substring_Length!) DO IF "!sub:~%%B,1!"=="" SET /a "Substring_Length&=~1<<%%A"
)
IF %Substring_Length% GTR %String_Length% GOTO strIndex_end
SET /A Searches=%String_Length%-%Substring_Length%
IF %Instance% GTR 0 (
FOR /L %%n IN (0,1,%Searches%) DO (
CALL SET StringSegment=%%String:~%%n,!Substring_Length!%%
IF "%~2" EQU "!StringSegment!" SET /A Instance-=1
IF !Instance! EQU 0 SET Index=%%n & GOTO strIndex_end
)) ELSE (
FOR /L %%n IN (%Searches%,-1,0) DO (
CALL SET StringSegment=%%String:~%%n,!Substring_Length!%%
IF "%~2" EQU "!StringSegment!" SET /A Instance+=1
IF !Instance! EQU 0 SET Index=%%n & GOTO strIndex_end
))
:strIndex_end
EXIT /B %Index%