簡體   English   中英

如何檢查參數(或變量)是否是批處理腳本中的數字

[英]How to check if a parameter (or variable) is a number in a Batch script

我需要檢查傳遞給 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%等於a3453d ,那么它會將varCheck設置為0 ,並且因為0不等於a3453d ,那么它將退出批處理。

(第 3 行的退出只是為了防止 if 語句由於某種原因決定不執行……XD。)

@hornzach - 你是如此接近,而且答案比其他人要簡單得多。

隱藏錯誤消息(至少在 win 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"

最簡單的正整數應該是:

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

這里的這篇文章中學到

做和上面一樣的事情。 有特殊字符的問題。 但是,解決方案是不同的方法。

@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)

我改用這個功能,它似乎對我有用,沒有任何問題......

腳本 (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.

我使用技術含量較低的方法。 它僅適用於整數並支持負值。

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。

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

我知道這是一個很老的線程,但我也遇到了這個問題。 到目前為止給出的一些建議(例如)不能處理輸入的“&”。 而且我想要一個“單行”解決方案(沒有 CALL 等),對於這種作為(部分)鍵盤輸入輸入的“毒葯”字符,它是“堅如磐石”的。 我的建議采用“白名單”/“灰姑娘”方法,逐位檢查有問題的變量 (varinput),簡單地挑選出“好的”變量並將它們連接到“varcleaned”。

設置 varcleaned=&& FOR /L %%i IN (0,1,10) DO (FOR %%j IN (AB C D 0 1 2 3 4) DO (IF ":varinput,~%%i,1!" EQU "%%j" (SET varcleaned=!varcleaned!%%j)))

我已經針對最常見的“毒葯”字符對其進行了測試 - 並且有效。 在給出的示例中,白名單是 A 到 D 和 0 到 4,並且有 11 輪(這意味着它為 varinput < 12 數字完成它的工作)。 因此,如果您希望將“數字”值作為 varcleaned,只需相應地更改白名單即可。 一旦你“清理”了變量,你就可以繼續上面提到的其他解決方案,比如“set /a varinput = %varcleaned% 2>nul”。 出於性能原因,我會盡可能減少走查和白名單的數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM