Регулярные выражения в 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_=