验证批处理文件中的用户输入

时间:2015-03-30 07:38:37

标签: batch-file

我有一个批处理文件,要求用户输入2个输入。然后创建/更新文本文件,其中包括用户输入的条目。这些条目必须是特定格式。

即。 (第一次输入) 信,信,号码,空间,数字,信,号码,号码,号码,空格信,信。

e.g。 AB52 7L056 TA (所有字母都必须大写)

(第二次输入) 信件,信件,信件,数字,信件,空间,(然后是11个数字)。

e.g。 EBH9E 12323405432

我还需要限制输入,以便在每个输入的末尾没有输入空格。到目前为止我的代码是:

@echo off
@echo This is a test :> dblank.txt
SET /P someVar=[Please enter STRING and press ENTER]
@echo [THIS IS THE STRING ENTERED] %someVar% >> dblank.txt
@echo This is another TEST :>> dblank.txt
SET /P someVar2=[Please enter NEXT STRING and press ENTER]
@echo [THIS IS THE SECOND STRING ENTERED] %someVar2% >> dblank.txt
@echo DOES IT WORK ???>> dblank.txt

有人可以帮忙吗? 非常感谢提前。

2 个答案:

答案 0 :(得分:0)

嗯,从用户那里读取任何输入并且然后验证它(并重复该过程,直到用户输入正确的输入),而限制输入是非常不同的em>到给定的格式,因此不接受无效字符。对于第一种方法,您可以使用先前建议的findstr命令。

前段时间我写了一个批处理程序,它实现了这种格式化的输入。这是它的帮助屏幕:

Read a line from keyboard with specific format

call :ReadFormattedLine var="mask"  [/M "message"]  [/P]  [/A|/W|/F]

The mask specify valid input characters per position via the following chars:

   #  -  Any digit
   _  -  Any letter
   +  -  A letter that is converted to uppercase
   ?  -  Any letter or digit
   @  -  Letter or digit, convert letter to uppercase

The following characters are just displayed/inserted at their positions:
   $  /  \  (  )  [  ]  :  ;  ,  .  -  space  letters  digits

Any character in the mask different than previous ones cause an error.

If /P (password) switch is given, input characters are displayed as asterisks.

Normally the input is completed when Enter key is pressed after read at least
one character, but the following switches changes this behavior.

   /A (auto):   Input is auto-completed after the last character; Enter key
                is ignored.
   /W (whole):  Enter key is accepted at first or last input positions only,
                that is, when input is empty or whole.
   /F (fields): Enter key fills the field with spaces and move the cursor to
                the next input field in the line.

To input a whole value terminated by Enter, use /W switch and insert any
character at the first position in the mask.

使用:ReadFormattedLine子程序,您可以通过以下方式解决问题:

call :ReadFormattedLine FirstInput="++## #+### ++" /M "First input: "
echo Input read: "%FirstInput%"

call :ReadFormattedLine SecondInput="+++#+ ###########" /M "Second input: "
echo Input read: "%SecondInput%"

您可以从this site下载子程序。

答案 1 :(得分:0)

根据this FINDSTR (Search for strings) reference,我们可以使用以下元字符来构造我们的正则表达式模式:

 ^     Line position: beginning of line
 $     Line position: end of line
 [ ]   Character class: one space
 [0-9] Range: decimal digit (n)
 [A-Z] Range: English alphabet letter in uppercase (L)

string template"regular expression pattern"

  • LLnn nLnnn LL"^[A-Z][A-Z][0-9][0-9][ ][0-9][A-Z][0-9][0-9][0-9][ ][A-Z][A-Z]$"
  • LLLnL nnnnnnnnnnn"^[A-Z]{3}[0-9][A-Z][ ][0-9]{11}$"

不幸的是,findstr正则表达式引擎不支持“{11}”或{3}(一个额外的量词,允许您指定令牌可以重复多少次),所以我们写这个可怕的模式:

"^[A-Z][A-Z][A-Z][0-9][A-Z][ ][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$"

不幸的是,FINDSTRlimited to a maximum of 15 character class terms within a regex并使用它会引发错误FINDSTR: Search string too long.(下面的解决方案)。

为方便用户使用,我不会将用户的输入限制为仅使用大写无其他空格

  • 信件案例:使用subroutine to convert variable contents to upper/lower case:toUcase子例程基于Aacinianswer here;
  • 空格FOR /F循环用于删除所有超额空间;而且,在第二种情况下,为了方便用户输入,可怕的11个字符可以被空格分割(参见下面的输出);
  • 15个字符类术语限制FOR /F循环用于拆分someVar2U变量并将每个部分区分开来。

在下一个脚本中,出于调试和演示的目的:

    省略
  • set /P命令:用%~1%~2脚本command line arguments替换用户的输入;
  • echo ...> dblank.txt重定向省略;
  • 一些其他自我解释的评论。

脚本

@echo OFF >NUL
SETLOCAL enableextensions disabledelayedexpansion

:: LLnn nLnnn LL
set "someVarU=%~1"
echo [THIS IS THE STRING ENTERED] [%someVarU%]
:: remove superabundant spaces
for /F "tokens=1-3*" %%G in ("%someVarU%") do set "someVar=%%G %%H %%I%%J"
:: convert to uppercase 
call :toUcase somevar somevarU
echo(%someVarU%|FindStr /R /C:"^[A-Z][A-Z][0-9][0-9][ ][0-9][A-Z][0-9][0-9][0-9][ ][A-Z][A-Z]$">nul
echo FindStr return %errorlevel% in [%somevarU%] 

:: LLLnL nnnnnnnnnnn
set "someVar2U=%~2"
echo [THIS IS THE SECOND STRING ENTERED] [%someVar2U%]
:: remove superabundant spaces
for /F "tokens=1-2*" %%G in ("%someVar2U%") do set "someVar2=%%G %%H%%I"
:: convert to uppercase
call :toUcase somevar2 somevar2U
rem {3} not supported: echo(%someVar2U%|FindStr /R /C:"^[A-Z]{3}[0-9][A-Z][ ][0-9]{11}">nul
:: 
set /A "myErrLevel=0"
for /F "tokens=1*" %%G in ("%someVar2U%") do (
    echo(%%G|FindStr /R /C:"^[A-Z][A-Z][A-Z][0-9][A-Z]$">nul
    if errorlevel 1  set /a "myErrLevel+=10"
    echo(%%H|FindStr /R /C:"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$">nul
    if errorlevel 1  set /a "myErrLevel+=20"
)
echo FindStr return %myErrLevel% in [%somevar2U%] 
ENDLOCAL
goto :eof


:toUcase
:: Based on https://stackoverflow.com/a/15650980/3439404 by Aacini
:: Converts variable contents to upper case
:: Usage: CALL :toUcase VAR_IN VAR_OUT
:: VAR_IN  = NAME of variable whose value is to be converted to upper case
:: VAR_OUT = NAME of variable to hold the converted value
:: Note: use variable NAMES in the CALL (i.e. pass both "by reference")
SETLOCAL enableextensions enabledelayedexpansion
set "_strToConvert=!%1!
for %%b in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    set _strToConvert=!_strToConvert:%%b=%%b!
)
:: do not break next line, keep "&" ampersands 
ENDLOCAL&set %2=%_strToConvert%&goto:eof

<强>输出

==>D:\bat\StackOverflow\29340733.bat " ab52  7i556    Ta  " " ebh9e 12345   123456"
[THIS IS THE STRING ENTERED] [ ab52  7i556    Ta  ]
FindStr return 0 in [AB52 7I556 TA]
[THIS IS THE SECOND STRING ENTERED] [ ebh9e 12345   123456]
FindStr return 0 in [EBH9E 12345123456]

==>D:\bat\StackOverflow\29340733.bat " 1b52  7i556    Ta  " " ebhe x2345   123456"
[THIS IS THE STRING ENTERED] [ 1b52  7i556    Ta  ]
FindStr return 1 in [1B52 7I556 TA]
[THIS IS THE SECOND STRING ENTERED] [ ebhe x2345   123456]
FindStr return 30 in [EBHE X2345123456]

==>