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