2

How can I check whether a variable in my batch file contains special characters or not? for example if my variable contains a file-name,then the file-name should not contain characters like \/ < > | : * " ? these.

@echo off
set param="XXX"
echo %param%| findstr /r "^[^\\/?%*:|"<>\.]*$">nul

if %errorlevel% equ 0 goto :next
echo "Invalid Attribute"

:next
echo correct

I used this link as a reference regex for validating folder name & file name

Zeale
  • 18
  • 5
acer
  • 305
  • 1
  • 5
  • 10
  • What have you tried so far? please share your attempts by editing your post... – aschipfl Nov 09 '15 at 09:11
  • actually i don't have any idea,can I use regex here – acer Nov 09 '15 at 09:17
  • 1
    Possible duplicate of [Escape user input in windows batch file](http://stackoverflow.com/questions/9910380/escape-user-input-in-windows-batch-file) – wOxxOm Nov 09 '15 at 09:46
  • 1
    I don't need to escape or replace,i just need to find that the variable have characters or not and i need to exit from the batch file,if the variable have characters – acer Nov 09 '15 at 09:50
  • 1
    Definite duplicate of http://stackoverflow.com/questions/5491383/find-out-whether-an-environment-variable-contains-a-substring – Marged Nov 09 '15 at 09:54
  • Any my personal suggestion: dump that batch and convert it into something wsh based. Wsh allows you to call function like `instr`: https://msdn.microsoft.com/en-us/library/wybb344c(v=vs.84).aspx – Marged Nov 09 '15 at 09:56
  • 1
    You'll definitely need to escape as you will have to state the characters literally in your script; for the rest there are two possible starting points: 1. string substitution like `if "%VAR%"=="%VAR:/=%"`, so the condition is true if `VAR` does not contain `/`; 2. a `for /F` loop like `for /F "tokens=2 delims=\/:` %C in ("%VAR%#") do, which executes the loop only if at least any of the given characters `\/:` occur; – aschipfl Nov 09 '15 at 09:58
  • I invite you to use the right words. A variable _always_ "have characters"! If you want to check if the variable contain **special** characters, you should use such term. I suggest you to edit your question and insert the "special" word... – Aacini Nov 09 '15 at 15:22
  • I edited my question with my batch file,somebody please help me to solve this out,here I used regex to identify special characters, if I use the filename without special character also,batchfile echo as invalid – acer Nov 09 '15 at 18:48

2 Answers2

6

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)>
Community
  • 1
  • 1
JosefZ
  • 22,747
  • 4
  • 38
  • 62
  • Thanks a lot,your answer is perfect and clear,worked for me. – acer Nov 10 '15 at 08:36
  • Nice solution and explanation. Small comment to your link [How Command Line Parameters Are Parsed](http://www.daviddeley.com/autohotkey/parameters/parameters.htm). The description how to escape command line parameters (for windows) is wrong, often it will work, but it's still not correct to use three carets. – jeb Nov 10 '15 at 09:27
1

You can change your findstr line to

set "param=Test < string"

cmd /v:on /c echo(^^!param^^! | findstr /r "^[^\\/?%%*:|<>\.\"]*$^" > nul

if %errorlevel% equ 0 ( 
echo OK
) ELSE (
  echo Invalid, special character found
)

This works, as the param will be expanded in the child cmd.exe process with delayed expansion.
It's unimportant if delayed expansion is enabled or not, the line works always.
And I changed the regex, as to search for a quote itself is a bit nasty.

jeb
  • 70,992
  • 15
  • 159
  • 202