0

I am really confused here. I have written a snippet of code in C# that is passed a possible file pathway. If it contains a character specified in a regex string, it should return false. However, the regex function Match refuses to find anything matching (I even set it to a singular character I knew was in the string), resulting in severe irritation from me. The code is:

static bool letterTest(string pathway)
{
    bool validPath = false;
    char[] c = Path.GetInvalidPathChars();
    string test = new string(c);
    string regex = "["+test+"]";
    string spTest = "^[~#%&*\\{}+<>/\"|]";

    Match match = Regex.Match(pathway, spTest);

    if (!match.Success)
    {
        validPath = true;
    }

    return validPath;
}

The string I pass to it is: @"C:/testing/invalid#symbol"

What am I doing wrong/misunderstanding with the regex, or is it something other than the regex that I have messed up?

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
HadesHerald
  • 131
  • 1
  • 7
  • 2
    this isn't a problem for Regex, just use `string.Contains()` – Jonesopolis Aug 27 '15 at 18:53
  • @Jonesopolis That tests for a substring, but `pathway.Any(c => Path.GetInvalidPathChars().Contains(c))` would work. – juharr Aug 27 '15 at 18:56
  • If you plan to play a bit with Regex, you should try using `string regex = "["+Regex.Escape(test)+"]";`. Since you obtain an array of symbols that cannot be used in folder path, and they contain special regex metacharacters, it is the safest way to handle that. However, here, you need to use LINQ as provided by some people. – Wiktor Stribiżew Aug 27 '15 at 19:41
  • If you are going to use your own invalid chars like shown, as told the caret is not needed (you _want_ to find the ones in the class). But, the regex isn't properly stringed as a double quoted string. Should be `string regex = "[~#%&*\\\\{}+<>/\"|]";` –  Aug 27 '15 at 22:15

5 Answers5

1

Remove the initial caret from your regex:

[~#%&*\\{}+<>/\"|]

You are requiring that the path begin with one of those characters. By removing that constraint, it will search the whole string for any of those characters.

But why not use the framework to do the work for you?

Check this out: Check if a string is a valid Windows directory (folder) path

Community
  • 1
  • 1
lintmouse
  • 5,079
  • 8
  • 38
  • 54
1

Instead of a regular expression you can just do the following.

static bool letterTest(string pathway)
{
    char[] badChars = Path.GetInvalidPathChars();
    return pathway.All(c => !badChars.Contains(c));
    // or
    // return !pathway.Any(c => badChars.Contains(c));
    // or
    // return badChars.All(bc => !pathway.Contains(bc));
    // or
    // return !badChars.Any(bc => pathway.Contains(bc));
}
juharr
  • 31,741
  • 4
  • 58
  • 93
0

Someone has already pointed out the caret that was anchoring your match to the first character. But there's another error you may not be aware of yet. This one has to do with your use of string literals. What you have now is a traditional, C-style string literal:

"[~#%&*\\{}+<>/\"|]"

...which becomes this regex:

[~#%&*\{}+<>/"|]

The double backslash has become a single backslash, which is treated as an escape for the following brace (\{). The brace doesn't need escaping inside a character class, but it's not considered a syntax error.

However, the regex will not detect a backslash as you intended. To do that, you need two backslashes in the regex, so there should be four backslashes in the string literal:

"[~#%&*\\\\{}+<>/\"|]"

Alternatively, you can use a C# verbatim string literal. Backslashes have no special meaning in a verbatim string. The only thing that needs special handling is the quotation mark, which you escape by adding another quotation mark:

@"[~#%&*\\{}+<>/""|]"
Alan Moore
  • 73,866
  • 12
  • 100
  • 156
-1

you have to escape the / literal

"^[~#%&*\\{}+<>\/\"|]"
maraaaaaaaa
  • 7,749
  • 2
  • 22
  • 37
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – JAL Aug 27 '15 at 19:47
  • This is wrong anyway. The forward-slash has no special meaning in regexes. You only have to escape it when it's being used as the regex *delimiter*, which is not an issue in C#. – Alan Moore Aug 27 '15 at 21:29
-2

Caret stands for negation of the character group. Removing it from spTest solves this issue.

 string spTest = "[~#%&*\\{}+<>/\"|]";
  • caret is only for negation when inside of the character class. His was an anchor to the beginning of the string. – maraaaaaaaa Aug 27 '15 at 21:32