Подтвердить что ты не робот

Регулярные выражения в 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 ++, которая, вероятно, является достижением), я бы ожидал, что такие простые выражения будут работать.

Любые идеи, что я делаю неправильно здесь?

4b9b3361

Ответ 1

Это работает для меня:

findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"

Если вы не используете параметр /c, аргумент <Strings> рассматривается как список строк поиска, разделенных пробелами, что делает пространство своего рода грубой заменой для конструкции |. (Пока ваши регулярные выражения не содержат пробелов, то есть.)

Ответ 2

Арг, мне лучше читать документацию. 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=

Ответ 3

Или, если можно, загрузите grep для windows.. Доступно гораздо больше функций, чем findstr.

Ответ 4

Простейший regex, который реализует одно и то же, возможно, просто добавьте необязательный минус к началу вашего исходного выражения:

^-?[0-9][0-9]*$

Ответ 5

Я понимаю, что это действительно старая должность, но подумал, что это может произойти в будущем, поэтому я быстро взломал немного более совершенное пакетное решение. Обычно я просто использовал 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_=

Ответ 6

Поддержка регулярных выражений в findstr довольно ограничена. Я предлагаю использовать Notepad++. Опция поиска в файлах поддерживает Perl-совместимые регулярные выражения; Результаты, показывающие имя файла, номер строки и соответствующий текст, могут быть легко скопированы в текстовый файл.