Pada baris perintah berbasis Windows NT (kebanyakan untuk XP atau lebih tinggi), apakah ada cara untuk memverifikasi jika switch yang disediakan hanya angka? Tergantung pada nomornya, saya ingin mengulang kode x beberapa kali
Secara pribadi, saya lebih suka metode dalam jawaban ini untuk: Pastikan pengguna memasukkan bilangan bulat . Gunakan prosesor perintah untuk melakukan semua pekerjaan itu. Anda dapat menyederhanakannya menjadi 2 x baris sebagai solusi minimal: 1 set /a NO_LINES=%~1.; 2 if %NO_LINES% NEQ %~1 goto ABORT.. Ketika keduanya sama - Variabel atau parameternya adalah numerik .
akan
Jawaban:
18
Diedit untuk memperbaiki regex sesuai komentar debham . Ternyata menambahkan spasi sebelum pipa setelah gema menambahkan spasi ke string pipa, yang merupakan pemecahan awal / akhir pencocokan garis sebelumnya. Regex dapat ditingkatkan lebih lanjut dengan membuang spasi putih di awal dan akhir.
Itu findstrperintahnya. Itu dapat mencari file dengan ekspresi reguler, seperti grepdi Linux. Itu juga dapat mencari input yang di-piped.
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if %errorlevel% equ 0 (
echo Valid number
)
Penjelasan
Parameter yang digunakan diatur ke dalam paramvariabel. Namun, tidak ada yang menghentikan Anda menggunakan parameter secara langsung ( %1untuk parameter pertama).
findstrdigunakan untuk mencari input pipa dengan /rbendera untuk regex.
Pola:
^ berarti awal baris.
[0-9]berarti digit. The *berarti sebelumnya diulang nol atau lebih kali. Jadi [0-9][0-9]*artinya satu digit, plus nol atau lebih digit. Dengan kata lain, setidaknya satu digit. Satu +atau beberapa kali sepertinya tidak didukung oleh findstr. Catatan yang [1-9]digunakan untuk digit pertama untuk melarang nol terkemuka - lihat komentar.
$ berarti end of line.
Sekarang, for for dalam batch untuk x jumlah kali ... jika x bukan angka yang valid, loop sebenarnya tidak berjalan sama sekali - itu hanya akan dilewati untuk baris berikutnya. Jadi tidak perlu memeriksa apakah input adalah angka yang valid!
@echo off
set param=%1
for /l %%a in (1,1,%param%) do (
echo %%a
)
Loop dilakukan dengan menggunakan for /l, di mana (x,y,z)berarti mulai dari x, kenaikan yhingga ztercapai. Dan itu diatur %%ake nomor / iterasi saat ini.
Catatan: ini sebenarnya gagal jika ada nol di depan, menyebabkan pemroses perintah memperlakukannya sebagai angka oktal. Lihat jawaban dbenham untuk solusi yang lebih baik.
Seperti yang tertulis, solusi ini akan gagal dengan parameter seperti "this 1 fails"FINDSTR harus melakukan pencocokan tepat. Seharusnya tidak melakukan pencocokan kata.
dbenham
@ Benham, terima kasih. Saya mencoba awal / akhir pencocokan baris sebelumnya, tetapi gagal karena gema melewati ruang ekstra. Diperbaiki sekarang
Bob
@CanadianLuke Anda mungkin ingin melihat hasil edit.
Bob
Nilai 09atau 010dapat menyebabkan masalah karena notasi oktal. Lihat jawaban saya untuk regex yang melarang notasi oktal.
dbenham
8
Berikut ini berfungsi dengan baik untuk saya. SET /a param=%1+0selalu kembali 0jika %1kosong atau tidak numerik. Kalau tidak, itu memberikan nomor yang diberikan.
SET /a param=%1+0
IF NOT %param%==0 ECHO Valid number
Ini akan gagal jika parameter = 0. Juga akan memperlakukan parameter seperti "1 + 1" sebagai angka, yang dapat menyebabkan masalah, tergantung pada persyaratan.
dbenham
7
Ini akan mendeteksi jika parameter pertama adalah bilangan asli yang valid (bilangan non-negatif).
@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
)
Jika Anda ingin membolehkan kutipan di sekitar angka, maka
@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
)
Catatan - nol di depan tidak diizinkan karena bets memperlakukannya sebagai oktal, sehingga nilai seperti 09tidak valid, dan 010memiliki nilai 8.
Terinspirasi oleh jawaban Bob yang luar biasa dengan tambahan berikut
Perbaiki logika tingkat kesalahan
Terapkan loop / sub DoWork yang berulang melalui angka dan lakukan aritmatika
:::::::::::::::
::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^>
Masalah dengan yang berikut ini adalah bahwa ia selalu mengembalikan 'Nomor valid' karena 'jika errorlevel 0' selalu benar karena fakta bahwa itu adalah perbandingan '> = 0', bukan perbandingan '== 0'.
@echo off
set param=%1
echo %param%| findstr /r "^[1-9][0-9]*$">nul
if errorlevel 0 (
echo Valid number
)
Bisakah Anda menambahkan beberapa penjelasan juga?
slhck
0
Saya tidak tahu mengapa tetapi pada sistem saya findstrperintah tidak berfungsi. Level kesalahan tidak diubah pada pertandingan atau tidak sama sekali.
Saya memang datang dengan metode lain
:: 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.
Ini adalah game yang menggunakan fungsi ini.
@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
.. Ketika keduanya sama - Variabel atau parameternya adalah numerik .Jawaban:
Diedit untuk memperbaiki regex sesuai komentar debham . Ternyata menambahkan spasi sebelum pipa setelah gema menambahkan spasi ke string pipa, yang merupakan pemecahan awal / akhir pencocokan garis sebelumnya. Regex dapat ditingkatkan lebih lanjut dengan membuang spasi putih di awal dan akhir.
Itu
findstr
perintahnya. Itu dapat mencari file dengan ekspresi reguler, sepertigrep
di Linux. Itu juga dapat mencari input yang di-piped.Penjelasan
Parameter yang digunakan diatur ke dalam
param
variabel. Namun, tidak ada yang menghentikan Anda menggunakan parameter secara langsung (%1
untuk parameter pertama).findstr
digunakan untuk mencari input pipa dengan/r
bendera untuk regex.Pola:
^
berarti awal baris.[0-9]
berarti digit. The*
berarti sebelumnya diulang nol atau lebih kali. Jadi[0-9][0-9]*
artinya satu digit, plus nol atau lebih digit. Dengan kata lain, setidaknya satu digit. Satu+
atau beberapa kali sepertinya tidak didukung olehfindstr
. Catatan yang[1-9]
digunakan untuk digit pertama untuk melarang nol terkemuka - lihat komentar.$
berarti end of line.Sekarang, for for dalam batch untuk x jumlah kali ... jika x bukan angka yang valid, loop sebenarnya tidak berjalan sama sekali - itu hanya akan dilewati untuk baris berikutnya. Jadi tidak perlu memeriksa apakah input adalah angka yang valid!
Loop dilakukan dengan menggunakan
for /l
, di mana(x,y,z)
berarti mulai darix
, kenaikany
hinggaz
tercapai. Dan itu diatur%%a
ke nomor / iterasi saat ini.Catatan: ini sebenarnya gagal jika ada nol di depan, menyebabkan pemroses perintah memperlakukannya sebagai angka oktal. Lihat jawaban dbenham untuk solusi yang lebih baik.
sumber
"this 1 fails"
FINDSTR harus melakukan pencocokan tepat. Seharusnya tidak melakukan pencocokan kata.09
atau010
dapat menyebabkan masalah karena notasi oktal. Lihat jawaban saya untuk regex yang melarang notasi oktal.Berikut ini berfungsi dengan baik untuk saya.
SET /a param=%1+0
selalu kembali0
jika%1
kosong atau tidak numerik. Kalau tidak, itu memberikan nomor yang diberikan.sumber
Ini akan mendeteksi jika parameter pertama adalah bilangan asli yang valid (bilangan non-negatif).
Jika Anda ingin membolehkan kutipan di sekitar angka, maka
Catatan - nol di depan tidak diizinkan karena bets memperlakukannya sebagai oktal, sehingga nilai seperti
09
tidak valid, dan010
memiliki nilai 8.sumber
Terinspirasi oleh jawaban Bob yang luar biasa dengan tambahan berikut
Masalah dengan yang berikut ini adalah bahwa ia selalu mengembalikan 'Nomor valid' karena 'jika errorlevel 0' selalu benar karena fakta bahwa itu adalah perbandingan '> = 0', bukan perbandingan '== 0'.
$ 0,02 saya
sumber
Anda dapat memvalidasi variabel apa pun jika jumlahnya:
sumber
sumber
Saya tidak tahu mengapa tetapi pada sistem saya
findstr
perintah tidak berfungsi. Level kesalahan tidak diubah pada pertandingan atau tidak sama sekali.Saya memang datang dengan metode lain
sumber
Ini adalah game yang menggunakan fungsi ini.
sumber