我需要检查传递给 Windows 批处理文件的参数是否为数值。检查也适用于变量会很好。
我找到了一个类似问题的答案,该命令与正则表达式一起使用。findstr
我确实尝试了该解决方案,但它并没有像我希望的那样工作(至少在 Windows 7 上)。
我的测试场景如下:
AA # not a valid number
A1 # not a valid number
1A # not a valid number
11 # a valid number
SET "var="&for /f "delims=0123456789" %%i in ("%1") do set var=%%i
if defined var (echo %1 NOT numeric) else (echo %1 numeric)
酌情替换%1
为%yourvarname%
对于± integers
(也测试前导零):
echo(%~1|findstr "^[-][1-9][0-9]*$ ^[1-9][0-9]*$ ^0$">nul&&echo numeric||echo not numeric
你可以试试这个。例如var
,传递的变量%var%
等于500
。
set /a varCheck=%var%
if %varCheck% == %var% (goto :confirmed) else (exit /B)
exit /B
:confirmed
:: You can use %var% here, and it should only be executed if it is numerical!
如果%var%
等于 eg a3453d
,那么它将被设置varCheck
为0
,并且因为0
不等于a3453d
,那么它将退出批处理。
(第 3 行的退出是为了以防 if 语句出于某种原因决定不执行……XD。)
最简单的正整数应该是:
IF 1%1 NEQ +1%1 echo Notnumeric!
如果还要考虑负数(连字符),这将起作用
SET number=%1
if 1%1 EQU +1%1 echo positive number
if %1==-%number:-=% echo negative number
在这里从这篇文章中学到
@hornzach - 你是如此接近,而且答案比其他人简单得多。
隐藏错误消息(至少赢得 7)重定向到标准错误输出(2)到 nul(一个特殊的文件,它悄悄地丢弃输出“bit-bucket”)
set /a varCheck = %var% 2>nul
然后您的其余答案适用于 4 个测试用例。
带有测试用例的完整答案:
call :CheckNumeric AA "#NOT A VALID NUMBER"
call :CheckNumeric A1 "#NOT A VALID NUMBER"
call :CheckNumeric 1A "#NOT A VALID NUMBER"
call :CheckNumeric 11 "#A VALID NUMBER"
call :CheckNumeric 1.23456789012345678901234567890.123456 "#NOT A VALID NUMBER"
goto :EOF
:CheckNumeric
@ECHO.
@ECHO Test %1
set /a num=%1 2>nul
if {%num%}=={%1} (
@ECHO %1 #A VALID NUMBER, Expected %2
goto :EOF
)
:INVALID
@ECHO %1 #NOT A VALID NUMBER, Expected %2
输出:
Test AA
AA #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test A1
A1 #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test 1A
1A #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
Test 11
11 #A VALID NUMBER, Expected "#A VALID NUMBER"
Test 1.23456789012345678901234567890.123456
1.23456789012345678901234567890.123456 #NOT A VALID NUMBER, Expected "#NOT A VALID NUMBER"
做和上面一样的事情。特殊字符有问题。然而,解决方案是不同的方法。
@echo off
cls
setlocal enabledelayedexpansion
if "%1"=="" (goto:eof) else (set _VAR2CHECK=%1)
for /l %%a in (0,1,9) do (
if defined _VAR2CHECK (set "_VAR2CHECK=!_VAR2CHECK:%%a=!") else (goto :end)
)
:end
if defined _VAR2CHECK (echo %1 #NOT A VALID NUMBER) else (echo %1 #A VALID NUMBER)
set "_VAR2CHECK="
endlocal
测试场景:
C:\>ISNUM 1A
1A #NOT A VALID NUMBER
C:\>ISNUM 11
11 #A VALID NUMBER
只需尝试除以 1。但它不适用于 Z 以外的数字(非相对整数或小数)。
set var=29
set /a number=%var% >nul 2>&1
set /a number=%number% / 1 >nul 2>&1
if "%var%" == "%number%" (echo numeric) else (echo NOT numeric)
我改用这个功能,它似乎对我有用,没有任何问题......
REM == Script variables =============================================
SET "NUMCODE=%1"
SET "NAME=%2"
REM == Main script ==================================================
CALL :Validate "NUMCODE"
IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL%
CALL :Validate "NAME"
IF ERRORLEVEL 1 EXIT /B %ERRORLEVEL%
ECHO Validation Complete and all variables passed validation.
REM == Functions ====================================================
:IsNumeric [string-value] [return-val]
SET "stringVal=%~1"
SET /A numericVal=%stringVal% > nul 2> nul
IF "%stringVal%"=="%numericVal%" (SET "%~2=1") ELSE (SET "%~2=0")
EXIT /B 0
:Validate
SET PASSEDVALIDATION=0
ECHO Validating %~1...
IF "%~1"=="NUMCODE" (
ECHO - Value: %NUMCODE%
IF NOT "%NUMCODE%"=="" SET PASSEDVALIDATION=1
IF "!PASSEDVALIDATION!"=="1" (
CALL :IsNumeric %NUMCODE% RETVAL
SET PASSEDVALIDATION=!RETVAL!
)
IF "!PASSEDVALIDATION!"=="1" (
IF NOT %NUMCODE% GEQ 1 SET PASSEDVALIDATION=0
)
IF "!PASSEDVALIDATION!"=="1" (
IF NOT %NUMCODE% LEQ 526 SET PASSEDVALIDATION=0
)
IF "!PASSEDVALIDATION!"=="0" (
ECHO - The first parameter is invalid, it can not be blank.
ECHO - Valid value is a number from 1 to 526.
ECHO - Leading zeros are not valid.
)
)
IF "%~1"=="NAME" (
ECHO - Value: %NAME%
IF NOT "%NAME%"=="" SET PASSEDVALIDATION=1
IF "!PASSEDVALIDATION!"=="0" (
ECHO - The second parameter is invalid, it can not be blank.
)
)
IF "!PASSEDVALIDATION!"=="0" (
ECHO - Failed validation.
EXIT /B 1
) ELSE (
ECHO - Passed validation.
)
EXIT /B 0
C:\mytestscript.bat 10 MrTest
Validating NUMCODE...
- Value: 10
- Passed validation.
Validating NAME...
- Value: MrTest
- Passed validation.
C:\mytestscript.bat 600
Validating NUMCODE...
- Value: 600
- The first parameter is invalid, it can not be blank.
- Valid value is a number from 1 to 526.
- Leading zeros are not valid.
- Failed validation.
C:\mytestscript.bat 10
Validating NUMCODE...
- Value: 10
- Passed validation.
Validating NAME...
- Value:
- The second parameter is invalid, it can not be blank.
- Failed validation.
我使用了一种技术含量更低的方法。它仅适用于整数并支持负值。
set "XVALUE=%~1"
set /A XVALUE=XVALUE
if "%XVALUE%" NEQ "%~1" goto :invalid_value
第一行获取命令行参数并将其放入 XVALUE。使用“引号”可以防止各种特殊字符出现问题。
第二行看起来很神秘,但是当 SET /A 的等号右侧有一个文本字符串时,它利用了这一点,它被解释为一个包含数值的环境变量。命令处理器解析假定的数值而不生成任何错误消息或设置 ERRORLEVEL。这样做总是会导致 XVALUE 被转换为有效的数值,无论传递给我们什么。
第三行是可选的,仅当您想严格要求参数是 -2147483648 到 2147483647 范围内的数值时才需要。如果您不使用if
测试,那么
if errorlevel
只接受可用于检查的数值:
set test_var=001
(
(if errorlevel %test_var% break ) 2>nul
)&&(
echo %test_var% is numeric
)||(
echo %test_var% is NOT numeric
)
set test_var=001X
(
(if errorlevel %test_var% break ) 2>nul
)&&(
echo %test_var% is numeric
)||(
echo %test_var% is NOT numeric
)
第一次检查会通过,第二次不会。虽然上面的脚本不能处理一元+
- 如果你也想处理这种情况,检查 - isInteger.bat