0

The symbols not allowed in filename or folder name in windows are \ / : * ? " < > |. I wrote a regex for it but not able to write regex to exclude " (double quotes).

Regex regex = new Regex(@"^[\\\/\:\*\?\'\<\>\|]+$");

Tried as below but it didnt work:

Regex regex = new Regex(@"^[\\\/\:\*\?\'\<\>\|&quot;]+$");

EDIT: I am particularly looking for code with regex itself and hence its not a duplicate.

Help is greatly appreciated. Thanks.

vinmm
  • 277
  • 1
  • 3
  • 14
  • 2
    Aren't you just looking for `^[^\\\/:*?"<>|]+$` ? Assuming you want to match a filename not containing those characters. – Paul-Etienne Nov 14 '17 at 12:36
  • 2
    Why don't you just escape double quote with `\"`? – zipa Nov 14 '17 at 12:37
  • 2
    In C#, there is a special method that you may uuse to check if a filename is valid. No need to use a regex. – Wiktor Stribiżew Nov 14 '17 at 12:39
  • 2
    @zipa To escape a double quote in a verbatim string literal it should be doubled. – Wiktor Stribiżew Nov 14 '17 at 12:41
  • Possible duplicate of [In C# check that filename is \*possibly\* valid (not that it exists)](https://stackoverflow.com/questions/422090/in-c-sharp-check-that-filename-is-possibly-valid-not-that-it-exists) – dnickless Nov 14 '17 at 13:11
  • @dnickless: I am particularly looking for code with regex itself and hence its not duplicate to above question. – vinmm Nov 15 '17 at 04:24
  • @Paul-Etienne: Its right but as Wiktor said, we will have to escape it with a double literal. Thanks Wiktor. – vinmm Nov 15 '17 at 04:25

2 Answers2

4

Instead of using Regex you could do something like this:

var invalidChars = new HashSet<char>(Path.GetInvalidFileNameChars());
var invalid = input.Any(chr => invalidChars.Contains(chr));
Allrameest
  • 4,364
  • 2
  • 34
  • 50
  • I am particularly looking for code with regex itself. But this solution works too. Thanks. – vinmm Nov 15 '17 at 04:26
2

@Allrameest answer using Path.GetInvalidFileNameChars() is probably the one you should use.

What I wanted to address is the fact that your regex is actually wrong or very ineffective (I don't know what exectly you wanted to do).

So, using:

var regex = new Regex(@"^[\\\/\:\*\?\'\<\>\|]+$");

mean you match a string which consists ONLY of "forbidden" characters (BTW, I think single quote ' is not invalid). Is it what you want? Don't think so. What you did is:

  • ^ start of the string
  • [...]+ invalid characters only (at least once)
  • $ end of the string

Maybe you wanted @"^[^...]+$" (hat used twice)?

Anyway, solution for your problem (with regex) is:

  • don't use ^ or $ just try to find any of those and bomb out quickly
  • in raw string (the one starting with @") you escape double quotes by doubling it.

So, the right regex is:

var regex = new Regex(@"[\\\/\:\*\?\""\<\>\|]");
if (regex.Match(filename).Success) {
    throw new ArgumentException("Bad filename");
}

Just find any and bomb out.


UPDATE by @JohnLBevan

var regex = new Regex(
    "[" + Regex.Escape(new string(Path.GetInvalidFileNameChars())) + "]");
if (regex.Match(filename).Success) {
    throw new ArgumentException("Bad filename");
}

(Not using string.Format(...) as this Regex should be static and precompiled anyway)

Milosz Krajewski
  • 1,160
  • 1
  • 12
  • 19
  • 1
    Or combine your answers `var regex = new Regex(string.Format("^[^{0}]$", Regex.Escape(new string(Path.GetInvalidFileNameChars()))));` / `var regex = new Regex(string.Format("[{0}]", Regex.Escape(new string(Path.GetInvalidFileNameChars()))));` – JohnLBevan Nov 14 '17 at 13:34
  • @Milosz: Perfect answer i was looking for. Thanks. – vinmm Nov 15 '17 at 04:30