【问题标题】:Windows batch file - validate user input environmental variable is hexadecimalWindows 批处理文件 - 验证用户输入环境变量是否为十六进制
【发布时间】:2012-02-10 16:22:19
【问题描述】:

在 Windows Server 2003 命令提示符下以交互方式运行的批处理文件中,SET /p 接受用户对环境变量的输入。如何确保用户输入仅包含十六进制字符(即 0123456789ABCDEF)?包含任何其他字符的输入应该会失败。

例如:

  • 02A13 应该没问题。
  • 3Du*23I 应该会失败。

逻辑应该是这样的:

:Get_Hex   
   Set /p _HexVal = Enter hex value:
   If not *ValidHexCheck* Echo Invalid input. Try again.&Goto Get_Hex
:Continue

ValidHexCheck 将被替换为真实代码。我不能使用 FINDSTR 的原因太愚蠢而无法进入这里。我想我可以在 FOR 循环中做到这一点。有人有好的想法吗?

【问题讨论】:

    标签: batch-file hex validation command-prompt


    【解决方案1】:

    小心 - 您可能不希望变量名中有空格,因此您需要删除 SET 语句中 = 之前的空格。

    一种解决方案是将所有十六进制数字都替换为空,看看是否还有剩余。

    @echo off
    setlocal enableDelayedExpansion
    :Get_Hex
    set "_HexVal="
    set /p _HexVal=Enter hex value:
    if not defined _HexVal echo You must enter a value. Try again.&goto Get_Hex
    set "test=!_HexVal!"
    for %%C in (0 1 2 3 4 5 6 7 8 9 A B C D E F) do if defined test set "test=!test:%%C=!"
    if defined test echo Invalid input. Try again.&goto Get_Hex
    

    我还添加了一个额外的测试以确保输入了某些内容。如果未输入任何内容,则保留当前值。这就是为什么必须在输入语句之前清除变量的原因。

    一种更简单的方法是使用 FINDSTR 查找仅包含 1 个或多个十六进制数字字符的行:

    @echo off
    setlocal enableDelayedExpansion
    :Get_Hex
    set "_HexVal="
    set /p "_HexVal=Enter hex value: "
    echo !_HexVal!|findstr /ri "^[0123456789ABCDEF][0123456789ABCDEF]*$" >nul || (
      echo Invalid input. Try again.
      goto Get_Hex
    )
    

    或者您可以使用 FINDSTR 查找非十六进制数字,但您必须再次验证是否有值。

    @echo off
    setlocal enableDelayedExpansion
    :Get_Hex
    set "_HexVal="
    set /p "_HexVal=Enter hex value: "
    if not defined _HexVal echo Invalid input. Try again.&goto Get_Hex
    echo !_HexVal!|findstr /ri "[^0123456789ABCDEF]" >nul && (
      echo Invalid input. Try again.
      goto Get_Hex
    )
    

    另一种方法是让 FOR /F 查找非十六进制数字。同样,您还必须验证是否存在值。

    @echo off
    setlocal enableDelayedExpansion
    :Get_Hex
    set "_HexVal="
    set /p "_HexVal=Enter hex value: "
    if not defined _HexVal echo Invalid input. Try again.&goto Get_Hex
    for /f "eol=0 delims=0123456789ABCDEFabcdef" %%A in ("!_HexVal!") do (
      echo Invalid input. Try again.
      goto Get_Hex
    )
    

    【讨论】:

    • 编辑 - 添加其他解决方案
    【解决方案2】:

    一种方法 - 将输入字符串中的每个十六进制字符替换为“”。
    如果结果不是“”,则说明存在无效字符;

    @echo off
    setlocal enabledelayedexpansion
    set alphabet=0123456789ABCDEF
    
    set input=DEADBEEF1234  
    rem you will need to handle empty input
    set test=%input%
    
    for /l %%c in (0,1,15) do (
        if [!test!] neq [] (
            set hexdigit=!alphabet:~%%c,1!
            call set test=%%test:!!hexdigit!!=%%
        )
    )
    
    if [%test%] neq [] (
        echo character: %test% in %input% is invalid
        goto :eof
    )
    
    echo %input% is valid
    

    对于 32 位值(不确定是否在 64 位上扩展)

    set input=deadbeef
    set test=
    set /a test=0x%input% >nul 2>&1
    if [%test%] equ [] echo invalid
    

    【讨论】:

    • 我也想到了 SET /A 测试。但我放弃了它,因为它会接受像1+1 这样的输入。算术运算符肯定不是有效的十六进制数字:)
    • 是的,这是一个很好的观点,任何运营商都会被接受
    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-10
    相关资源
    最近更新 更多