You can't use echo %param%| findstr /r ...
nor even echo !param!| findstr /r ...
. For more info on how pipes are parsed and processed, look at this question and answers: Why does delayed expansion fail when inside a piped block of code.
Use an auxiliary (temporary) file as follows:
@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
:testloop
set "param="
set /P "param=string to test (hit <Enter> to end)> "
if not defined param goto :endtest
>"%temp%\33605517.txt" echo(!param!
rem next line for debugging purposes
for /F "usebackq delims=" %%G in ("%temp%\33605517.txt") do set "_marap=%%G"
findstr /r ".*[<>:\"\"/\\|?*%%].*" "%temp%\33605517.txt" >nul
if %errorlevel% equ 0 (
echo !errorlevel! Invalid !param! [!_marap!]
) else (
echo !errorlevel! correct !param! [!_marap!]
)
goto :testloop
:endtest
ENDLOCAL
goto :eof
.*[<>:\"\"/\\|?*%%].*
regular expression explanation:
.*
- zero or more occurences of any character in front of a string;
[<>:\"\"/\\|?*%%]
any one character in set of reserved characters:
<
(less than);
>
(greater than);
:
(colon);
"
(double quote) escaped as \"\"
(findstr and batch parser);
/
(forward slash);
\
(backslash) escaped as \\
(findstr);
|
(vertical bar or pipe);
?
(question mark);
*
(asterisk);
%
(percent sign) escaped (for batch parser) as %%
; in fact, %
is not reserved for NTFS
file system but requires special escaping in pure cmd
and/or in a batch script;
.*
- zero or more occurences of any character at end of string.
Here are more links to some questions on SO with exhaustive answers by Aacini, DBenham, Jeb (among others). Exciting, fascinating reading...
and to detailed How Command Line Parameters Are Parsed by David Deley, © 2009 (Updated 2014)
Output:
string to test (hit <Enter> to end)> n<m
0 Invalid n<m [n<m]
string to test (hit <Enter> to end)> n>m
0 Invalid n>m [n>m]
string to test (hit <Enter> to end)> n:m
0 Invalid n:m [n:m]
string to test (hit <Enter> to end)> n/m
0 Invalid n/m [n/m]
string to test (hit <Enter> to end)> n\m
0 Invalid n\m [n\m]
string to test (hit <Enter> to end)> n|m
0 Invalid n|m [n|m]
string to test (hit <Enter> to end)> n?m
0 Invalid n?m [n?m]
string to test (hit <Enter> to end)> n*m
0 Invalid n*m [n*m]
string to test (hit <Enter> to end)> n"m
0 Invalid n"m [n"m]
string to test (hit <Enter> to end)> nm
1 correct nm [nm]
string to test (hit <Enter> to end)> nm.gat
1 correct nm.gat [nm.gat]
string to test (hit <Enter> to end)> n%m.gat
0 Invalid n%m.gat [n%m.gat]
string to test (hit <Enter> to end)>