Question: How to compare user entered string that contains special characters, for example 7^7%7&7=7"7!7
within Windows Batch?
Unfinished Code:
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
)
Expect output:
> URL: 7^7%7&7=7"7!7
> Nice
> URL: 42
> Bad
p.s. user entered string is actually valid url in real situation so all valid url characters are possible input, quotes is included for more general situation similar to this problem.
CodePudding user response:
The main issue is the unbalanced quotes. The condition:
if "%str1%"=="7^7%%7&7=7"7!7^" (
echo Nice
) else (
echo Bad
)
should no longer return a syntax error on its own (given that delayed variable expansion is disabled), as long as the variable str1
does not contain (unbalanced) quotes on its own. As you can see, the %
-symbol must be doubled, independent on quotation, but other special characters must only be escaped when they appear outside of quotes. The last quotation mark is escaped, so it is not recognised as such.
But this will still fail if you enter 7^7%7&7=7"7!7
into the prompt because of the quotation mark in str1
, because (immediate) variable expansion happens before special characters are detected. The only way to prevent the condition from failing, independent on the user entry, you must use delayed variable expansion:
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
As you may recognise, the right expression of the comparison looks quite strange now, since delayed expansion may require some additional escaping, depending on whether the expression contains exclamation marks.
To prevent the need of such quite confusing and illegible escaped expressions, assign the comparison string to a variable first while delayed expansion is still disabled:
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