如何比较用户输入的字符串与批处理文件中的特殊字符?

How to compare user entered string with special characters in batch file?

问题:如何比较 用户输入的包含特殊字符的字符串,例如 Windows 批次中的 7^7%7&7=7"7!7

未完成的代码:

set/p str1=URL: 
rem if %str1%==7^7%7&7=7"7!7 (  // syntax error
rem if "%str1%"=="7^^7%%7^&7=7^"7!7" (  // still syntax error
    echo Nice
) else (
    echo Bad
)

预期输出:

> URL: 7^7%7&7=7"7!7
> Nice
> URL: 42
> Bad

p.s。 用户输入的字符串在实际情况下实际上是有效的url所以所有valid url characters都可以输入,引号包含在与此问题类似的更一般情况下。

主要问题是报价不平衡。条件:

if "%str1%"=="7^7%%7&7=7"7!7^" (
    echo Nice
) else (
    echo Bad
)

本身不应 return 语法错误(假设 delayed variable expansion 被禁用),只要变量 str1 不包含(不平衡的)引号自己的。如您所见,% 符号必须加倍,独立于引号,但其他特殊字符只有在出现在引号之外时才必须转义。最后一个引号被转义,因此无法识别。

但是,如果您在提示中输入 7^7%7&7=7"7!7,由于 str1 中的引号,这仍然会失败,因为(立即)变量扩展发生在检测到特殊字符之前。防止条件失败的唯一方法,独立于用户输入,必须使用延迟变量扩展:

set /P str1="URL: "
rem // At first, enable delayed variable expansion:
setlocal EnableDelayedExpansion
rem /* Then apply it by enclosing variables with `!!` rather than `%%`;
rem    there are now even more complex escape sequences necessary though: */
if "!str1!"=="7^^7%%7&7=7"7^^!7^" (
    echo Nice
) else (
    echo Bad
)
endlocal

您可能已经意识到,比较的正确表达式现在看起来很奇怪,因为延迟扩展可能需要一些额外的转义,具体取决于表达式是否包含感叹号。

为了避免使用这种非常混乱和难以辨认的转义表达式,在延迟扩展仍然被禁用的情况下,首先将比较字符串分配给一个变量:

set /P str1="URL: "
rem /* Predefine comparison expression; you always have to double `%`-symbols,
rem    and you still need to escape some special characters that appear unquoted,
rem    but escaping sequences do not depend on whether or not there is a `!`: */
set "cmp1=7^7%%7&7=7"7!7^"
rem // At first, enable delayed variable expansion:
setlocal EnableDelayedExpansion
rem // Then apply it by enclosing variables with `!!` rather than `%%`:
if "!str1!"=="!cmp1!" (
    echo Nice
) else (
    echo Bad
)
endlocal