msdos - findstr windows 2003
Expresiones regulares en findstr (5)
Estoy haciendo una pequeña validación de cadenas con findstr
y su findstr
/r
para permitir expresiones regulares. En particular me gustaría validar los enteros.
El regex
^[0-9][0-9]*$
funcionó bien para números no negativos, pero como ahora apoyo números negativos, también lo intenté
^([1-9][0-9]*|0|-[1-9][0-9]*)$
para enteros positivos o negativos o cero.
La expresión regular funciona bien teóricamente . Lo probé en PowerShell y coincide con lo que quiero. Sin embargo, con
findstr /r /c:"^([1-9][0-9]*|0|-[1-9][0-9]*)$"
no lo hace
Aunque sé que findstr
no tiene el soporte de findstr
más avanzado (incluso debajo de Notepad ++, que probablemente sea un gran logro), habría esperado que esas expresiones simples funcionaran.
¿Alguna idea de lo que estoy haciendo mal aquí?
Argh, debería haber leído mejor la documentación . findstr
parecer, findstr
no admite alternaciones ( |
).
Por lo tanto, es probable que vuelva a múltiples invocaciones o reemplace todo con un analizador personalizado eventualmente.
Esto es lo que hago por ahora:
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=
Es posible un regex
más simple que logre lo mismo, solo agregue un signo menos negativo al inicio de su expresión original:
^-?[0-9][0-9]*$
Esto funciona para mí:
findstr /r "^[1-9][0-9]*$ ^-[1-9][0-9]*$ ^0$"
Si no usa la opción /c
, el argumento <Strings>
se trata como una lista de cadenas de búsqueda separadas por espacios, lo que hace que el espacio sea un tipo de reemplazo bruto para |
construir. (Mientras sus expresiones regulares no contengan espacios, es decir).
Me doy cuenta de que esta es una publicación muy antigua, pero pensé que podría surgir en el futuro, así que rápidamente pirateé una solución por lotes más avanzada. Normalmente solo usaría powershell, python, ruby o vbs. Es mucho más desafiante en un lenguaje por lotes, pero ¿por qué no? :-PAG
@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_=
O si puedes, descarga grep para windows. . Muchas más características que findstr
proporciona.