5

LastIndexOf文字を特定の文字列に取り込むために、Windowsバッチスクリプトに関数を実装する必要があります。

例:次の文字列が与えられた場合、文字の最後のインデックスを取得する必要があります'/'

/name1/name2/name3
            ^

だから私は値を取得する必要があります:

12
4

3 に答える 3

8

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 は 1 番目、2 は 2 番目、-1 は最後、-2 は最後から 2 番目などになります。

于 2012-10-22T14:37:41.557 に答える
6

(注: 率直に言って、ここで実際のDOS バッチ ファイルを求める質問は 1 つしか見たことがないので、Windows バッチ ファイルを想定しています。ほとんどの人は、灰色のウィンドウがあるものを単に「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%
于 2012-10-22T10:29:05.353 に答える
0

私はこの質問が少し古いことを知っていますが、文字列内の部分文字列 (任意の長さ) の場所を見つけることができる関数が必要で、私の目的に合わせて dbenham のソリューションを適応させました。この関数は、元の質問で求められているように、文字列内の個々の文字でも機能し、特定のインスタンスを検索できます (dbenham が示唆するように)。

この関数を使用するには、実際の文字列を渡す必要があります。Dbenham は、これが実際の変数を渡すよりも少ない文字をサポートしていることに注目していますが、このバリアントは (特にパイプを使用して) より再利用可能であることがわかりました。

3 番目の引数は、最後から検索することを指定する負の数を使用して、検索する必要があるインスタンスを取得します。返されるインデックスは、文字列の先頭から部分文字列の最初の文字までのオフセットです。

@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%
于 2014-04-08T05:29:00.953 に答える