Dans la ligne de commande basée sur Windows NT (principalement pour XP ou supérieur), existe-t-il un moyen de vérifier si un commutateur fourni est un nombre uniquement? Selon le nombre, je veux qu'il boucle le code x nombre de fois
Dans la ligne de commande basée sur Windows NT (principalement pour XP ou supérieur), existe-t-il un moyen de vérifier si un commutateur fourni est un nombre uniquement? Selon le nombre, je veux qu'il boucle le code x nombre de fois
Réponses:
Modifié pour corriger l'expression régulière selon le commentaire de Debham . Il s'avère que l'ajout d'un espace avant le tuyau après l'écho ajoute un espace à la chaîne canalisée, ce qui a rompu la correspondance de début / fin de ligne précédemment. Le regex pourrait être encore amélioré en supprimant les espaces blancs au début et à la fin.
Voilà la findstrcommande. Il peut rechercher des fichiers avec des expressions régulières, un peu comme grepsous Linux. Il peut également rechercher une entrée canalisée.
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if %errorlevel% equ 0 (
echo Valid number
)
Le paramètre utilisé est défini dans la paramvariable. Cependant, rien ne vous empêche d'utiliser directement le paramètre ( %1pour le premier paramètre).
findstrest utilisé pour rechercher l'entrée canalisée avec le /rdrapeau pour regex.
Le motif:
^ signifie début de ligne.
[0-9]signifie un chiffre. Le *signifie la précédente répétée zéro ou plusieurs fois. Signifie donc [0-9][0-9]*un chiffre, plus zéro ou plusieurs chiffres. En d'autres termes, au moins un chiffre. La +ou les fois ne semblent pas être prises en charge par findstr. Notez qu'il [1-9]est utilisé pour le premier chiffre pour interdire les zéros non significatifs - voir les commentaires.
$ signifie fin de ligne.
Maintenant, une boucle for en lot pour x nombre de fois ... si x n'est pas un nombre valide, la boucle ne s'exécute pas du tout - elle est simplement ignorée pour la ligne suivante. Il n'est donc pas nécessaire de vérifier si l'entrée est un nombre valide!
@echo off
set param=%1
for /l %%a in (1,1,%param%) do (
echo %%a
)
La boucle se fait en utilisant for /l, où les (x,y,z)moyens commencent à x, incrémenter yjusqu'à ce que zsoit atteint. Et il définit %%ale nombre / itération actuel.
Remarque: cela échoue en fait s'il y a un zéro en tête, ce qui oblige le processeur de commandes à le traiter comme un nombre octal. Voir la réponse de dbenham pour une meilleure solution.
"this 1 fails"FINDSTR devrait faire une correspondance exacte. Il ne doit pas faire de correspondance de mots.
09ou 010pourrait causer des problèmes en raison de la notation octale. Voir ma réponse pour regex qui interdit la notation octale.
Ce qui suit fonctionne très bien pour moi. SET /a param=%1+0renvoie toujours 0si %1est vide ou non numérique. Sinon, il fournit le numéro donné.
SET /a param=%1+0
IF NOT %param%==0 ECHO Valid number
Cela détectera si le premier paramètre est un nombre naturel valide (entier non négatif).
@echo off
echo %1|findstr /xr "[1-9][0-9]* 0" >nul && (
echo %1 is a valid number
) || (
echo %1 is NOT a valid number
)
Si vous souhaitez autoriser des guillemets autour du nombre, alors
@echo off
echo "%~1"|findstr /xr /c:\"[1-9][0-9]*\" /c:\"0\" >nul && (
echo %~1 is a valid number
) || (
echo %~1 is NOT a valid number
)
Remarque - les zéros non significatifs sont interdits parce que le lot les traite comme octaux, donc une valeur comme 09n'est pas valide et 010a une valeur de 8.
Inspiré par l' excellente réponse de Bob avec les ajouts suivants
:::::::::::::::
::CountTo.bat
:::::::::::::::
@echo off
::This is the number to test
if "%1"=="" goto :Usage
set param=%1
set matchPattern="^[1-9][0-9]*$"
::test if param matches matchPattern, quietly
:: (redirect stdout to nul, and stderr to stdout)
echo %param%|findstr /r %matchPattern%>nul 2>&1
:: check for errorlevel 1 or higher. errorlevel 0 is handled as
:: an unchecked fall-through
if errorlevel 1 goto :MyHandleErrorCode
::Success (errorlevel ! >= 1) so proceed.
echo %param% is a valid number
echo (matches findstr /r %param% %matchPattern%)
echo findstr returned errorlevel 0
::any other code that the batch file needs to do goes here
echo.
echo Iterating from 1 to %param%
echo.
for /l %%i in (1,1,%param%) do call :DoWork %%i
::anything else,
:: .
:: .
::cleanup
:: .
:: .
::exit the batch file here, skipping embedded subroutines
goto :eof
:::::::::::::::::::::::::
:: Main work subroutine
:::::::::::::::::::::::::
:DoWork
set /a offset = %1 - 1
set /a square = %1 * %1
echo item %1
echo offset: %offset%
echo square: %square%
echo.
goto :eof
:::::::::::::::::::::::
:: Error handler code
:::::::::::::::::::::::
:MyHandleErrorCode
echo.
echo CountTo %param%
echo %param% is not a valid number
echo (does not match findstr /r %param% %matchPattern%)
echo findstr returned errorlevel ^>= 1
:: error code doesn't have a goto :eof, we want to drop through to :Usage
::::::::
:Usage
::::::::
echo.
echo Usage:
echo. CountTo ^<someNumber^>
Le problème avec ce qui suit est qu'il retourne toujours «Numéro valide» car «si le niveau d'erreur 0» est toujours vrai car il s'agit d'une comparaison «> = 0», et non d'une comparaison «== 0».
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if errorlevel 0 (
echo Valid number
)
mon 0,02 $
Vous pouvez valider n'importe quelle variable si son nombre:
SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")
set xx=33
echo %xx%
SET /a %xx%+0 2>nul >nul && echo all Digits
set xx=3x3
echo %xx%
SET /a %xx%+0 2>nul >nul || echo No Digits
Je ne sais pas pourquoi mais sur mon système, la findstrcommande n'a pas fonctionné. Le niveau d'erreur n'était pas modifié lors d'une correspondance ou d'aucune correspondance.
J'ai trouvé une autre méthode
:: Look for all digits. Parse the string and use all the digits as
:: delimiters. If the entire string is a digit then we will get an empty
:: parse value.
SET ALL_DIGITS=0
FOR /F "tokens=* delims=0123456789" %%a IN ("%VALUE%") DO (
IF "[%%a]" EQU "[]" SET ALL_DIGITS=1
)
IF %ALL_DIGITS% EQU 0 (
ECHO ERROR: %VALUE% is not all numbers
)
:main
set /p input=text
if %input% equ 0 goto valid
set /a inputval="%input%"*1
if %inputval% equ 0 goto invalid
goto valid
:invalid
echo Input is not an integer.
:valid
echo Input is an integer.
Voici un jeu qui utilise cette fonction.
@echo off
:main
set /a guessmin=1
set /a guessmax=100
set /a guessrand=%random% %%100 +1
echo.
:check
if %guessmin% equ %guessmax% goto fail
set /p input=- Pick a number %guessmin% - %guessmax%:
set /a inputval="%input%"*1
if %inputval% equ 0 goto invalid
if %inputval% gtr %guessmax% goto invalid
if %inputval% lss %guessmin% goto invalid
if %inputval% gtr %guessrand% goto high
if %inputval% lss %guessrand% goto low
if %inputval% equ %guessrand% goto mid
:invalid
echo Please enter a valid number.
echo.
goto check
:high
echo Your guess was too high.
echo.
set /a guessmax=%inputval%-1
goto check
:low
echo Your guess was too low.
echo.
set /a guessmin=%inputval%+1
goto check
:mid
echo Your guess was correct. The game will now reset.
set /p input=- Press enter to play again.
cls
goto main
:fail
echo You actually managed to lose because there is only
echo one number remaining. That number is %guessrand%.
set /p input=- Press enter to lose again.
cls
goto main
set /a NO_LINES=%~1.; 2if %NO_LINES% NEQ %~1 goto ABORT.. Lorsque les deux sont égaux - La variable ou le paramètre est numérique .