Регулярные выражения в findstr
Я делаю небольшую проверку строки с findstr и /r флаг для регулярных выражений. В частности, я хотел бы проверить целые числа.
регулярное выражение
^[0-9][0-9]*$
отлично работал для неотрицательных чисел, но так как я теперь поддерживаю отрицательные числа, я попытался
^([1-9][0-9]*|0|-[1-9][0-9]*)$
для положительных или отрицательных целых чисел или нуля.
регулярное выражение работает нормально теоретически. Я тестировал его в PowerShell и ее соответствует тому, что я хочу. Однако с
findstr /r /c:"^([1-9][0-9]*|0|-[1-9][0-9]*)$"
это не так.
пока я это знаю findstr не имеет самой передовой поддержки регулярных выражений (даже ниже Notepad++, что, вероятно, является большим достижением), я ожидал бы, что такие простые выражения будут работать.
любые идеи, что я делаю неправильно здесь?
5 ответов
это работает для меня:
findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"
если вы не используете  на <Strings> аргумент рассматривается как разделенный пробелом список строк поиска, что делает пространство своего рода грубой заменой для | строительство.  (Если ваши регулярные выражения не содержат пробелов, то есть.)
тьфу, надо было читать документация лучше. findstr по-видимому, не поддерживает чередования (|).
поэтому я, вероятно, вернусь к нескольким вызовам или замене всего этого пользовательским синтаксическим анализатором.
Это то, что я делаю сейчас:
set ERROR=1
rem Test for zero
echo %1|findstr /r /c:"^0$">nul 2>&1
if not errorlevel 1 set ERROR=
rem Test for positive numbers
echo %1|findstr /r /c:"^[1-9][0-9]*$">nul 2>&1
if not errorlevel 1 set ERROR=
rem Test for negative numbers
echo %1|findstr /r /c:"^-[1-9][0-9]*$">nul 2>&1
if not errorlevel 1 set ERROR=
или, если можете, скачайте grep для windows.. Гораздо больше возможностей, чем findstr обеспечивает.
проще regex это позволяет достичь того же, просто добавьте необязательный минус в начало исходного выражения:
^-?[0-9][0-9]*$
Я понимаю, что это очень старый пост, но думал, что это может появиться в будущем, поэтому я быстро взломал немного более продвинутая замес раствора. Обычно я бы просто использовал powershell, python, ruby или vbs. Это намного сложнее на пакетном языке, но почему бы и нет. :- P
        @ECHO OFF
        REM The _Ignore_ variable ignores text turning search if needed
        SET _Ignore_=Ignore_something_if_you_need
        REM Set the _Debug_ variable if you want to see all the output.
        SET _Debug_=
        REM Save this as a batch file and test it by passing
        REM Usage: 
        REM Example 1:
        REM IsItTextOrIsItANumberRegxExample.bat 123
        REM Results:Found Number:"123"
        REM Example 2:
        REM IsItTextOrIsItANumberRegxExample.bat Michael123
        REM Results:Found Number:"Michael123"
        CALL:--CheckString %1
        GOTO :Done
        :--CheckString
        SET __CheckString__=%~1
        SET _RETURN_LETTERS_=""
        SET _RETURN_NUMBERS_=""
        REM Using EnableDelayedExpansion to more completely Expand the for loop results and pack in the results. 
        SETLOCAL ENABLEDELAYEDEXPANSION
        FOR /F "tokens=1*" %%A IN ('Echo %__CheckString__%^|findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"') DO (
            IF DEFINED _Debug_ ECHO Debug:%%A
            If %ERRORLEVEL% EQU 0 (
                IF NOT "%%A"=="%_Ignore_%" (
                    IF NOT "%%A"==" " (
                        SET __ReturnNumber__=%%A
                        SET __ReturnNumber__=!__ReturnNumber__: =!
                    )
                )
            )
        )
        ENDLOCAL && SET _RETURN_NUMBERS_=%__ReturnNumber__%
        REM Note: SETLOCAL is used twice because sometimes variable output will add spaces when using two similar for loops.
        SETLOCAL ENABLEDELAYEDEXPANSION
        FOR /F "tokens=1*" %%A IN ('Echo %__CheckString__%^|findstr /r "^[a-z][A-Z]*[0-9]*"') DO (
            IF DEFINED _Debug_ ECHO DEBUG:%%A
            If %ERRORLEVEL% EQU 0 (
                IF NOT "%%A"=="%_Ignore_%" (
                    IF NOT "%%A"==" " (
                        SET __ReturnLetters__=%%A
                    )
                )
            )
        )
        ENDLOCAL && SET _RETURN_LETTERS_=%__ReturnLetters__%
        GOTO:EOF
        :Done
        IF DEFINED _RETURN_NUMBERS_ ECHO Found Number:"%_RETURN_NUMBERS_%"
        IF DEFINED _RETURN_LETTERS_ ECHO Found Letters:"%_RETURN_LETTERS_%"
        REM Cleanup:
        SET _Ignore_=
        SET _RETURN_NUMBERS_=
        SET _RETURN_LETTERS_=
        SET _Ignore_=
        SET _Debug_=
