В командной строке на основе Windows NT (в основном для XP или выше) есть ли способ проверить, является ли предоставленный переключатель только числом? В зависимости от числа, я хочу, чтобы он перебрал код x количество раз
Лично я предпочитаю метод в этом ответе для: Убедитесь, что пользователь ввел целое число . Используйте командный процессор, чтобы сделать всю эту работу. Вы можете упростить его до 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флагом regex.
Шаблон:
^ означает начало строки.
[0-9]означает цифру. Эти *средства предыдущих повторяются ноль или более раз. Так [0-9][0-9]*означает одну цифру плюс ноль или более цифр. Другими словами, хотя бы одна цифра. В +один или несколько раз , кажется, не будет поддерживаться findstr. Обратите внимание, что [1-9]используется для первой цифры, чтобы запретить ведущие нули - см. Комментарии.
$ означает конец строки.
Теперь цикл for в пакете для 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текущий номер / итерации.
Примечание: на самом деле происходит сбой, если есть начальный ноль, в результате чего командный процессор обрабатывает его как восьмеричное число. Смотрите ответ Дбенхэма для лучшего решения.
Как написано, это решение не будет работать с таким параметром, как "this 1 fails"FINDSTR должен выполнить точное совпадение. Это не должно делать совпадение слов.
Дбенхем
@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
Это не удастся, если параметр = 0. Также будет обрабатывать такой параметр, как «1 + 1», как число, что может вызвать проблемы, в зависимости от требований.
Дбенхем
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
)
Примечание: начальные нули не допускаются, поскольку пакетный режим обрабатывает их как восьмеричные, поэтому значение like 09недопустимо и 010имеет значение 8.
Вдохновлен отличным ответом Боба со следующими дополнениями
Исправьте логику уровня ошибки
Реализуйте цикл / подпрограмму 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
)
Можете ли вы добавить некоторые объяснения, пожалуйста?
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
)
: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
set /a NO_LINES=%~1
.; 2if %NO_LINES% NEQ %~1 goto ABORT
.. Когда два равны - переменная или параметр является числовым .Ответы:
Отредактировано, чтобы исправить регулярное выражение в соответствии с комментарием Debham . Оказывается, что добавление пробела перед каналом после эха добавляет пробел к переданной по конвейеру строке, что ранее нарушало совпадение начала / конца строки. Регулярное выражение может быть улучшено путем удаления пробелов в начале и в конце.
Там
findstr
команда. Он может искать файлы с регулярными выражениями, какgrep
в Linux. Он также может искать ввод по каналу.объяснение
Используемый параметр устанавливается в
param
переменную. Однако ничто не мешает вам использовать параметр напрямую (%1
для первого параметра).findstr
используется для поиска входных данных с/r
флагом regex.Шаблон:
^
означает начало строки.[0-9]
означает цифру. Эти*
средства предыдущих повторяются ноль или более раз. Так[0-9][0-9]*
означает одну цифру плюс ноль или более цифр. Другими словами, хотя бы одна цифра. В+
один или несколько раз , кажется, не будет поддерживатьсяfindstr
. Обратите внимание, что[1-9]
используется для первой цифры, чтобы запретить ведущие нули - см. Комментарии.$
означает конец строки.Теперь цикл for в пакете для x количество раз ... если x не является допустимым числом, цикл фактически вообще не запускается - он просто пропускается для следующей строки. Таким образом, нет необходимости проверять, является ли ввод действительным числом!
Цикл завершается с использованием
for /l
, где(x,y,z)
означает началоx
, с шагомy
доz
достижения. И это устанавливает%%a
текущий номер / итерации.Примечание: на самом деле происходит сбой, если есть начальный ноль, в результате чего командный процессор обрабатывает его как восьмеричное число. Смотрите ответ Дбенхэма для лучшего решения.
источник
"this 1 fails"
FINDSTR должен выполнить точное совпадение. Это не должно делать совпадение слов.09
или010
может вызвать проблемы из-за восьмеричной записи. Смотрите мой ответ для регулярного выражения, которое запрещает восьмеричное обозначение.Следующее работает очень хорошо для меня.
SET /a param=%1+0
всегда возвращает значение,0
если%1
оно пустое или не числовое. В противном случае он предоставляет данный номер.источник
Это обнаружит, является ли первый параметр действительным натуральным числом (неотрицательное целое число).
Если вы хотите разрешить кавычки вокруг числа, то
Примечание: начальные нули не допускаются, поскольку пакетный режим обрабатывает их как восьмеричные, поэтому значение like
09
недопустимо и010
имеет значение 8.источник
Вдохновлен отличным ответом Боба со следующими дополнениями
Проблема со следующим заключается в том, что он всегда возвращает «Действительное число», потому что «если уровень ошибки 0» всегда истинен из-за того, что это сравнение «> = 0», а не «== 0».
мои $ .02
источник
Вы можете проверить любую переменную, если ее номер:
источник
источник
Я не знаю почему, но в моей системе
findstr
команда не работала. Уровень ошибки не изменялся во время матча или не совпадал.Я придумала другой метод, хотя
источник
Вот игра, которая использует эту функцию.
источник