我需要在Windows批處理腳本中實現一個函數,以將LastIndexOf字符轉換爲給定的字符串。LastIndexOf在Windows批處理
例如:給出下面的字符串,我需要獲得字符'/'
的最後一個索引:
/name1/name2/name3
^
所以我需要得到的值:
12
我需要在Windows批處理腳本中實現一個函數,以將LastIndexOf字符轉換爲給定的字符串。LastIndexOf在Windows批處理
例如:給出下面的字符串,我需要獲得字符'/'
的最後一個索引:
/name1/name2/name3
^
所以我需要得到的值:
12
(注:我假設Windows批處理文件,因爲坦率地說,我只看到一個單一的問題,在這裏要求一個實際的DOS批處理文件。大多數人只是簡單地將「DOS」錯誤地分配給任何具有灰色窗口的東西-on黑等寬的文本,而不知道什麼他們實際上談論的)
通過它只是循環,更新索引,當您去:
@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%
喬伊的解決方案工作,但要找到字符是硬編碼的,並且相對較慢。
這是一個快速的參數化函數,可以在字符串中找到任何字符(除了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可能是第一,第二,第二,-1倒數第二,等等。
我知道這個問題現在有點老了,但我需要一個函數,可以找到一個子字符串的位置任何長度)在一個字符串中,並適合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%
該代碼工作正常,但我創建了一個函數使用您的代碼,函數打印結果,但從不返回,你知道爲什麼嗎?謝謝你的幫助! –
由於我沒有看到你的代碼,我不知道爲什麼它不會返回。但是,我知道它爲什麼要打印結果:您仍然在那裏有「回聲」。至於爲什麼它不返回我只能猜測。我的猜測是你沒有寫一個函數,只是用'goto'而不是'call:label'來調用標籤。 – Joey
+1;一個簡單直接的解決方案,雖然相對較慢。 – dbenham