Перевірте лише чисельний вхід у пакетному файлі


10

Чи є в командному рядку Windows NT (в основному для XP або вище) спосіб перевірити, чи надається комутатор лише число? Залежно від кількості, я хочу, щоб він переглянув код x кількість разів


1
Особисто я віддаю перевагу методу в цій відповіді: Переконайтесь, що користувач ввів ціле число . Використовуйте командний процесор, щоб зробити все це. Ви можете спростити його до 2-х рядків як мінімальне рішення: 1 set /a NO_LINES=%~1.; 2. if %NO_LINES% NEQ %~1 goto ABORT. Коли два рівні - Змінна або параметр є числовим .
буде

Відповіді:


18

Відредаговано, щоб виправити регулярний вираз відповідно до коментаря debham . Виявляється, що додавання пробілу перед трубкою після відлуння додає простір до трубопроводу, який був тим, що порушив початок / кінець рядка, що збігався раніше. Регекс можна вдосконалити, відкинувши пробіли на початку та в кінці.


Там є findstrкоманда. Він може шукати файли з регулярними виразами, як і grepв Linux. Він також може шукати трубопровідний ввід.

@echo off

set param=%1

echo %param%| findstr /r "^[1-9][0-9]*$">nul

if %errorlevel% equ 0 (
    echo Valid number
)

Пояснення

Використовуваний параметр встановлюється у paramзмінну. Однак нічого не зупиняє вас безпосередньо використовувати параметр ( %1для першого параметра).

findstrвикористовується для пошуку по трубному вводу з /rпрапором для регулярного вираження.

Шаблон:

  • ^ означає початок рядка.

  • [0-9]означає цифру. Засіб *попередній повторював нуль або більше разів. Так [0-9][0-9]*означає одна цифра плюс нуль або більше цифр. Іншими словами, принаймні одна цифра. Схоже, +це не підтримується одним чи кількома разів findstr. Зверніть увагу, що [1-9]використовується для першої цифри, щоб заборонити провідні нулі - дивіться коментарі.

  • $ означає кінець рядка.


Тепер, цикл for batch у кількості x разів ... якщо x не є дійсним числом, цикл насправді взагалі не працює - він просто пропускається для наступного рядка. Тож не потрібно перевіряти, чи вхід є дійсним номером!

@echo off

set param=%1

for /l %%a in (1,1,%param%) do (
    echo %%a
)

Цикл робиться за допомогою for /l, де (x,y,z)засоби починаються з x, приріст до, yпоки не zбуде досягнуто. І він встановлює %%aпоточне число / ітерацію.

Примітка: це насправді не вдається, якщо є провідний нуль, через що командний процесор розглядає його як восьмеричне число. Дивіться відповідь dbenham для кращого рішення.


Відмінне пояснення! І простий у використанні
канадський Люк

1
Як було написано, це рішення не вдасться з таким параметром, як "this 1 fails"FINDSTR повинен точно відповідати. Він не повинен відповідати слова.
dbenham

@dbenham Дякую Я раніше спробував збіг початку / кінця рядків, але це не вдалося через ехо, пройшовши додатковий пробіл. Виправлено зараз.
Боб

@CanadianLuke Ви можете поглянути на редагування.
Боб

Значення 09або 010може спричинити проблеми через восьмеричні позначення. Дивіться мою відповідь на регулярний вираз, який відключає восьмеричні позначення.
dbenham

8

Наступне працює дуже добре для мене. SET /a param=%1+0завжди повертається, 0якщо %1порожній чи не числовий. В іншому випадку він надає задане число.

SET /a param=%1+0
IF NOT %param%==0 ECHO Valid number

4
Це не вдасться, якщо параметр = 0. Також буде розглядати такий параметр, як "1 + 1", як число, що може спричинити проблеми залежно від вимог.
dbenham

7

Це визначить, чи є перший параметр дійсним натуральним числом (невід'ємне ціле число).

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

Якщо ви хочете дозволити цитати навколо числа, то

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

Зауважте: провідні нулі заборонені, оскільки партія розглядає їх як восьмеричні, тому значення типу 09недійсне і 010має значення 8.


3

Натхненний чудовою відповіддю Боба з наступними доповненнями

  • Виправити логіку рівня помилок
  • Реалізуйте цикл / підрядчик DoWork, який перебирається через число і виконує деяку арифметику

:::::::::::::::
::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^>

Проблема з наступним полягає в тому, що він завжди повертає "Дійсне число", оскільки "якщо рівень помилок 0" завжди відповідає дійсності через те, що це порівняння '> = 0', а не порівняння '== 0'.

@echo off

set param=%1

echo %param%| findstr /r "^[1-9][0-9]*$">nul

if errorlevel 0 (
    echo Valid number
)

мої $ 02


Ну, виправили рівень помилок і на моєму. Пряме числове порівняння, а не автоматичне проходження.
Боб

2

Ви можете перевірити будь-яку змінну, якщо її номер:

SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")

0
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

2
Чи можете ви також додати трохи пояснень?
slhck

0

Не знаю чому, але в моїй системі findstrкоманда не працювала. Рівень помилок не змінювався в матчі чи не збігався.

Хоча я придумав інший метод

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

-1
: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.

Ось гра, яка використовує цю функцію.

@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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.