2012-10-22 3 views

답변

6

(참고 :

/name1/name2/name3 
      ^

그래서 내가 값을 얻을 필요가 : 다음과 같은 문자열을 감안할 때, 나는 문자 '/'의 마지막 인덱스를 얻을 필요가 나는 솔직히, 지금까지 실제 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% 
+0

코드는 정상적으로 작동하지만 코드를 사용하여 함수를 만들었지 만 함수는 결과를 인쇄하지만 결코 반환하지 않습니다. 왜 그런지 알고 있습니까? 당신의 도움을 주셔서 감사합니다! –

+0

코드가 표시되지 않아서 왜 반환되지 않는지 알 수 없습니다. 나는 왜 그것이 결과를 출력 하는지를 안다 : 당신은 여전히 ​​거기에 'echo'를 가지고있다. 그것이 왜 돌아 오지 않는지에 대해서만 나는 짐작할 수 있습니다. 내 생각 엔 함수를 작성하지 않고'call : label' 대신에'goto'라는 라벨을 붙인 것입니다. – Joey

+0

+1; 상대적으로 느리지 만 간단한 직선적 인 해결책입니다. – dbenham

8

조이의 솔루션은 작동하지만, 찾을 수있는 문자 하드 코드되며 상대적으로 느립니다.

다음은 빠르며 문자열 내에서 임의의 문자 (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 

이 찾아 occurance 추가 인수를 지정 소요 더 일반적인 :indexOf 기능을 만들기 위해 많은 수정을하지 않을 것입니다. 음수는 역순으로 검색하도록 지정할 수 있습니다. 따라서 1은 1 일, 2는 2, -1은 마지막, -2는 끝에서 두 번째 등이 될 수 있습니다.

0

이 질문은 약간 오래된 것이지만 부분 문자열의 위치를 ​​찾을 수있는 함수가 필요했습니다 (어떤 길이의 문자열이라도), 내 목적을 위해 dbenham의 솔루션을 채택했습니다. 이 함수는 원래 질문에서와 같이 문자열 내의 개별 문자와 함께 작동하며 특정 인스턴스를 검색 할 수 있습니다 (dbenham에서 제안한 것처럼).

이 함수를 사용하려면 실제 문자열을 전달해야합니다. Dbenham은 실제 변수를 전달하는 것보다 적은 수의 문자를 지원하지만이 변형은 특히 파이프와 함께 재사용이 가능하다는 사실을 발견했습니다.

세 번째 인수는 찾을 수있는 인스턴스를 취하며 끝에서 검색 할 음수를 지정합니다. 돌려 주어지는 인덱스는, 캐릭터 라인의 선두로부터 부분 캐릭터 라인의 최초의 캐릭터에의 오프셋 (offset)입니다.

@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%