【问题标题】:validate user input in batch file验证批处理文件中的用户输入
【发布时间】:2015-03-30 07:38:36
【问题描述】:

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

即(第一个输入) 字母, 字母, 数字 number,space,number,letter,number,number,number, 空格字母,letter.

例如AB52 7L056 TA (所有字母必须大写)

(第二个输入) 字母,字母,字母,数字,字母,空格,(然后是 11 个数字)。

例如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

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

【问题讨论】:

  • 您需要的是Findstr => 使用正则表达式搜索文件中的文本模式。 然后...当您现在如何它有效...像this example 一样使用它
  • 查看了 FINDSTR,它似乎在文件中搜索字符串?我需要强制运行批处理文件的用户以正确的格式输入字符串。然后将输入的字符串保存在批处理文件创建的 txt 文件中。
  • 我仍然建议使用Findstr,因为您需要一个“正则表达式”匹配。尝试使用临时名称保存该文件,进行检查,如果没问题.. 重命名并继续,如果不,警告用户并删除临时文件。
  • 更多 var 示例,如您所愿:stackoverflow.com/a/15730788/1601332 此功能必读:stackoverflow.com/questions/8844868/…

标签: batch-file


【解决方案1】:

嗯,读取用户的任何输入并然后验证它(并重复该过程直到用户输入正确的输入)与限制输入是非常不同的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下载子程序。

【讨论】:

  • 这正是我想要的。我建立了我的例程来围绕这个创建一个文本文件,它工作得很好。我确实需要在发送到文件的用户输入周围添加几行文本,但克服了这一点,事情看起来不错,感谢您的努力,这是一个很好的答案,对我的帮助无穷无尽。再次感谢。
【解决方案2】:

根据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。基于Aacinianswer here:toUcase子程序;
  • spacesFOR /F 循环用于移除所有多余的空间;此外,在第二种情况下,为了方便用户输入,可怕的 11 个字符可以用空格分隔(参见下面的输出);
  • 15 个字符类术语限制FOR /F 循环用于拆分 someVar2U 变量并将每个部分分开处理。

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

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

脚本

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

==>

【讨论】:

    猜你喜欢
    • 2010-10-15
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多