<http://www.netikka.net/tsneti/info/tscmd106.htm>
Copyright © 2003-2011 by Prof. Timo Salmi  
Last modified Fri 15-Jul-2011 13:46:01

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



106} How to test whether a variable is a non-negative integer?

This is one of the items which arose from a solution I needed myself. Test for a decimal (10-base) non-negative integer. The original solution is given after the simpler one below:
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Do a regular expression (/r) findstr complement

  echo %s%|findstr /r "[^0-9]">nul
  if %errorlevel% GTR 0 (set isInteger=true) else (set isInteger=false)
  ::
  :: Show the result

  echo %s%
  echo isInteger=%isInteger%
  ::
  endlocal & goto :EOF

Examples of output
  C:\_D\TEST>cmdfaq 1234
  1234
  isInteger=true
or
  C:\_D\TEST>cmdfaq FF
  FF
  isInteger=false
or
  C:\_D\TEST>cmdfaq 2x
  2x
  isInteger=false

Actually, a non-negative integer!

More fully
  @echo off & setlocal enableextensions
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Do a regular expression (/r) findstr complement and avoid the octal trap

  echo %s%|findstr /r "[^0-9]">nul||set isDecInteger=true
  if defined isDecInteger if not "%s:~1,2%"=="" if "%s:~0,1%"=="0" set IsDecInteger=
  ::
  :: Show the result

  if defined IsDecInteger (
    echo %s% is a regular, non-negative integer
    ) else (
    echo %s% is not a regular, non-negative integer
    )
  ::
  endlocal & goto :EOF

Another findstr formulation (for the first code option) to avoid the octal trap:
  echo %s%|findstr /b /e /v /r "0 [1-9][0-9]*">nul

Originaly, I had
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Get its length, counting from zero
  set charCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1)
  set /a charCount=%charCount%-1
  ::
  :: Test that only valid characters are present

  set isInteger=true
  for /l %%c in (0,1,%charCount%) do (
    set si=!s:~%%c,1!
    echo 1234567890|findstr /l "!si!">nul
    if !errorlevel! GTR 0 set isInteger=false
    )
  ::
  :: Show the result

  echo %s%
  echo isInteger=%isInteger%
  ::
  endlocal & goto :EOF

Examples of output
  C:\_D\TEST>cmdfaq 1234
  1234
  isInteger=true
or
  C:\_D\TEST>cmdfaq FF
  FF
  isInteger=false

The solution can be expanded to other numeric or alphabetic validity tests. For example to test if a variable is a positive decimal number.
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Get its length, counting from zero

  set charCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1)
  set /a charCount=%charCount%-1
  ::
  :: Test that only valid characters are present

  set isNumeric=true
  set pointCount=0
  for /l %%c in (0,1,%charCount%) do (
    set si=!s:~%%c,1!
    echo 1234567890.|findstr /l "!si!">nul
    if !errorlevel! GTR 0 set isNumeric=false
    if [!si!]==[.] set /a pointCount+=1
    )
  if %pointCount% GTR 1 set isNumeric=false
  ::
  :: Show the result

  echo %s%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq 12.34
  12.34
  isNumeric=true
or
  C:\_D\TEST>cmdfaq 1..
  1..
  isNumeric=false

Or, more concisely
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 Parameter
    goto :EOF)
  ::
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Test if non-valid characters are present

  set isNumeric=true
  echo %s%|findstr "[^0-9.]">nul
  if %errorlevel% EQU 0 set isNumeric=false
  ::
  :: Count the decimal points in the variable s

  set pointCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if [!si!]==[.] set /a pointCount+=1
    )
  if %pointCount% GTR 1 set isNumeric=false
  ::
  :: Show the result

  echo %s%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF

Another example. The parameter to be given is a time parameter in the HH:MM format. Test for its validity.
  @echo off & setlocal enableextensions enabledelayedexpansion
  if "%~1"=="" (
    echo Usage: %~f0 TimeParameterHH:MM
    goto :EOF)
  ::
  :: Test for the time parameter validity
  :: Get the parameter into a variable

  set s=%~1
  ::
  :: Get its length and count the number of colons

  set charCount=0
  set pointCount=0
  for /l %%c in (0,1,255) do (
    set si=!s:~%%c,1!
    if defined si set /a charCount+=1
    if [!si!]==[:] set /a pointCount+=1
    )
  ::
  :: Test that only valid characters are present

  set isNumeric=true
  echo %s%|findstr "[^0-9:]">nul
  if %errorlevel% EQU 0 set isNumeric=false
  ::
  :: Test for the right composition

  if %pointCount% GTR 1 set isNumeric=false
  if %charCount% GTR 5 set isNumeric=false
  ::
  :: Get the components

  for /f "tokens=1,2 delims=:" %%a in ("%s%") do (
  set shour=%%a
  set sminute=%%b)
  if not defined sminute set sminute=0
  ::
  :: Test that the time is within bounds

  if %shour% GTR 23 set isNumeric=false
  if %sminute% GTR 59 set isNumeric=false
  ::
  :: Show the result

  echo s=%s%
  echo shour=%shour%
  echo sminute=%sminute%
  echo isNumeric=%isNumeric%
  ::
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq 13:58
  s=13:58
  shour=13
  sminute=58
  isNumeric=true
or
  C:\_D\TEST>cmdfaq 25:11
  s=25:11
  shour=25
  sminute=11
  isNumeric=false

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups Jun 21 2005, 12:03 am [M]
  Google Groups Jan 13 2007, 5:55 pm [M]
  JsiFaq
  IsNumeric