24

我需要检查传递给 Windows 批处理文件的参数是否为数值。检查也适用于变量会很好。

我找到了一个类似问题的答案,该命令与正则表达式一起使用。findstr

我确实尝试了该解决方案,但它并没有像我希望的那样工作(至少在 Windows 7 上)。

我的测试场景如下:

AA  # not a valid number
A1  # not a valid number
1A  # not a valid number

11  # a valid number
4

10 回答 10

54
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%

于 2013-07-11T03:53:33.660 回答
15

对于± integers也测试前导零):

echo(%~1|findstr "^[-][1-9][0-9]*$ ^[1-9][0-9]*$ ^0$">nul&&echo numeric||echo not numeric
于 2013-07-11T05:03:03.490 回答
8

你可以试试这个。例如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,那么它将被设置varCheck0,并且因为0不等于a3453d,那么它将退出批处理。

(第 3 行的退出是为了以防 if 语句出于某种原因决定不执行……XD。)

于 2013-07-11T03:05:52.577 回答
7

最简单的正整数应该是:

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

在这里从这篇文章中学到

于 2019-06-18T16:07:25.593 回答
6

@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"
于 2016-05-14T14:24:31.020 回答
1

做和上面一样的事情。特殊字符有问题。然而,解决方案是不同的方法。

@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
于 2014-05-29T14:02:14.600 回答
1

只需尝试除以 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)
于 2019-08-05T21:00:04.040 回答
0

我改用这个功能,它似乎对我有用,没有任何问题......

脚本 (mytestscript.bat)

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.
于 2018-08-08T19:41:04.113 回答
0

我使用了一种技术含量更低的方法。它仅适用于整数并支持负值。

set "XVALUE=%~1"
set /A XVALUE=XVALUE
if "%XVALUE%" NEQ "%~1" goto :invalid_value

第一行获取命令行参数并将其放入 XVALUE。使用“引号”可以防止各种特殊字符出现问题。

第二行看起来很神秘,但是当 SET /A 的等号右侧有一个文本字符串时,它利用了这一点,它被解释为一个包含数值的环境变量。命令处理器解析假定的数值而不生成任何错误消息或设置 ERRORLEVEL。这样做总是会导致 XVALUE 被转换为有效的数值,无论传递给我们什么。

第三行是可选的,仅当您想严格要求参数是 -2147483648 到 2147483647 范围内的数值时才需要。如果您不使用if测试,那么

  • 通过在它们前面加上 0 或 0x,您可以获得对八进制和十六进制数字的支持。
  • 如果有人使用非常小或大的数字,例如 -9999999999999 或 9999999999999,则 XVALUE 将设置为允许的最小值或最大值,即 -2147483648 和 2147483647。
  • 如果有人使用诸如“hello”之类的垃圾,则 XVALUE 设置为 0。如果它类似于 123x456,则解析器在“x”处停止,XVALUE 设置为 123。
于 2020-09-18T07:02:02.583 回答
0

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

于 2020-11-11T13:23:08.513 回答