0

I am looking to create a list of file inside a folder, all matching a regex. But the regex crash whenever I put a path containing backslash inside the regex.

string test = @"C:\TEMP"; // or "C:\\TEMP"
Regex reg = new Regex(test + "\\" + "tstNL02" + @"_(.*).csv"); // it crash here

FileList = Directory.GetFiles(test).Where(path => reg.IsMatch(path)).ToList();

ArgumentException: parsing "C:\TEMP\tstNL02_(.*).csv" - Unrecognized escape sequence \T.

As far as I know, using a @ or escaping the backslash should prevent the regex from interpreting backslashes in a string as an escaping character (and if I remove test from the regex but leave the \\, regex doesn't crash).

If I put @"C:\\TEMP" the Regex doesn't parse any and the match fail C:\\TEMP\tstNL02_(.*).csv

I fixed my problem by going another way but I was wondering why and how to fix this backslash-in-a-variable thing ?

Edit: problem didn't came from regex but from the fact I was using the same string for regex and Directory.GetFiles. Adding escaping backslashes to the string so Regex worked correctly would cause Directory.GetFiles to not escape those added backslashes, thus not matching files

Niavart
  • 132
  • 2
  • 15
  • `\T` is not a valid regex escape. You want to double the backslash, `@"\\"`, not `"\\"` – Wiktor Stribiżew Nov 15 '19 at 12:33
  • @WiktorStribiżew `\T` is not a valid escape because I don't want it to be one. Adding @ before my "\\" doesn't change anything `ArgumentException: parsing "C:\TEMP\\tstNL02_(.*).csv" - Unrecognized escape sequence \T.` Problem is Regex keep interpreting my backslash and if I escape it, it escape both ! – Niavart Nov 15 '19 at 12:36
  • But you should double backlashes everywhere to match literal backslashes, also `@"C:\TEMP"` => `@"C:\\TEMP"` – Wiktor Stribiżew Nov 15 '19 at 12:38
  • It's not the regex that interprets stuff. The pattern is wrong. If you use `\\ ` in a normal literal, it creates a single `\ ` character in the pattern. What you tried created `\t`. If you want to match a backslash you need to escape it *in the pattern itself*. The final string should contain *two* backslashes. That means either using `@"\\"` or `"\\\\"` – Panagiotis Kanavos Nov 15 '19 at 12:39
  • This means you should use `string test = @"C:\\TEMP\\";` and `new Regex(test + "tstNL02" + @"_(.*).csv")` – Panagiotis Kanavos Nov 15 '19 at 12:40
  • @WiktorStribiżew all it does it doubling them everything in the result as well `C:\\TEMP\\tstNL02_(.*).csv` and it doesn't match any file. I should add that the variable 'C:\\Temp" is not mine and is supposed to be retrieved from a server – Niavart Nov 15 '19 at 12:41
  • It works fine - see [regex demo](http://regexstorm.net/tester?p=C%3a%5c%5cTEMP%5c%5ctstNL02_%28.*%29%5c.csv&i=C%3a%5cTEMP%5ctstNL02_Something.csv) of `Regex reg = new Regex(@"C:\\TEMP\\tstNL02_(.*)\.csv");` – Wiktor Stribiżew Nov 15 '19 at 12:43
  • 1
    It seems you do not need a regex here at all: `var fileList = Directory.GetFiles(@"C:\Test", "*.csv").Where(p => Path.GetFileName(p).StartsWith("tstNL02_")).ToList();` – Wiktor Stribiżew Nov 15 '19 at 12:46
  • Well I'm stumped. I tried every solution (with regex) you and Panagiotis proposed and none worked (no match found). The solution with no regex worked but I had already found another way which suit me more (`.Where(path => { var real_file = path.Split('\\').Last(); return reg.IsMatch(real_file); })` and `Regex reg = new Regex("tstNL02" + @"_(.*).csv");`) But I still don't understand why the Regex refuse to work with my path – Niavart Nov 15 '19 at 12:54
  • @WiktorStribiżew I found out why none of your solutions worked .. While the string containing my path was correctly escaping (or not) for the Regex, it was also used for the `Directory.GetFiles` which didn't need that much backslash escaping. And for some reason, it was still finding the files but `GetFiles` was adding a backslash in results... Which didn't match with the regex... It seem there is no way to use the same string for the regex AND Directory.GetFiles (unless I heavily parse it every time) – Niavart Nov 15 '19 at 13:05
  • 1
    True, you might probably use `Regex.Unescape(test)` with the `GetFiles` in this concrete example. Or just `.Replace(@"\\", @"\")` – Wiktor Stribiżew Nov 15 '19 at 13:08
  • Both `Unescape` and `GetFiles` worked great :) But since my variable (`test`) is recovered from a server (and I have no control over its value), I'll stick to matching values with only the filename. But I understand why it wasn't working :D Thanks ! – Niavart Nov 15 '19 at 13:23

0 Answers0