27

I am currently looking for a regex that can help validate a file path e.g.:

C:\test\test2\test.exe
Dan
  • 379
  • 2
  • 5
  • 8

10 Answers10

39

I decided to post this answer which does use a regular expression.

^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$

Works for these:

\\test\test$\TEST.xls
\\server\share\folder\myfile.txt
\\server\share\myfile.txt
\\123.123.123.123\share\folder\myfile.txt
c:\folder\myfile.txt
c:\folder\myfileWithoutExtension

Edit: Added example usage:

if (Regex.IsMatch (text, @"^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$"))
{
  // Valid
}

*Edit: * This is an approximation of the paths you could see. If possible, it is probably better to use the Path class or FileInfo class to see if a file or folder exists.

agent-j
  • 27,335
  • 5
  • 52
  • 79
27

I would recommend using the Path class instead of a Regex if your goal is to work with filenames.

For example, you can call Path.GetFullPath to "verify" a path, as it will raise an ArgumentException if the path contains invalid characters, as well as other exceptiosn if the path is too long, etc. This will handle all of the rules, which will be difficult to get correct with a Regex.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    59 seconds before my answer of the same thing, Bump for speed! – Random Developer Jun 20 '11 at 19:06
  • Could you provide a validation example please? – Dan Jun 20 '11 at 19:09
  • @Dan here is an example, note that the path can be UNC or local: if(Directory.Exists(Path.GetDirectoryName(@"C:\Windows\win.ini"))) { /*Directory exists and valid*/ } – Random Developer Jun 20 '11 at 19:24
  • The problem is that in some situations (esp. high-performance code) you really don't want to have to catch exceptions to validate user-input. It's disappointing that .NET doesn't have a `Path.TryParse` or `FileInfo.TryParse` method which avoids exceptions entirely. Another reason is if you're using a debugger then every time `Path`'s constructor throws an `ArgumentException` the debugger will break - and while you can opt to not break on `ArgumentException` it doesn't let you ignore only `ArgumentException` thrown from `Path` - so if you're SOL if you need to break elsewhere. – Dai Aug 26 '21 at 03:03
16

This is regular expression for Windows paths:

(^([a-z]|[A-Z]):(?=\\(?![\0-\37<>:"/\\|?*])|\/(?![\0-\37<>:"/\\|?*])|$)|^\\(?=[\\\/][^\0-\37<>:"/\\|?*]+)|^(?=(\\|\/)$)|^\.(?=(\\|\/)$)|^\.\.(?=(\\|\/)$)|^(?=(\\|\/)[^\0-\37<>:"/\\|?*]+)|^\.(?=(\\|\/)[^\0-\37<>:"/\\|?*]+)|^\.\.(?=(\\|\/)[^\0-\37<>:"/\\|?*]+))((\\|\/)[^\0-\37<>:"/\\|?*]+|(\\|\/)$)*()$

And this is for UNIX/Linux paths

^\/$|(^(?=\/)|^\.|^\.\.)(\/(?=[^/\0])[^/\0]+)*\/?$

Here are my tests:

Win Regex

Unix Regex

These works with Javascript

EDIT I've added relative paths, (../, ./, ../something)

EDIT 2 I've added paths starting with tilde for unix, (~/, ~, ~/something)

raythurnevoid
  • 2,652
  • 1
  • 25
  • 24
7

The proposed one is not really good, this one I build for XSD, it's Windows specific:

^(?:[a-zA-Z]\:(\\|\/)|file\:\/\/|\\\\|\.(\/|\\))([^\\\/\:\*\?\<\>\"\|]+(\\|\/){0,1})+$
Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
Alexander
  • 471
  • 1
  • 4
  • 6
  • correction - have to remove " otherwise throws error while using – Umesh May 18 '15 at 03:32
  • This one worked better for me (detected all UNC paths I sent to it), but I'm not familiar enough with regex to know if the " should be removed or escaped (e.g. changed to "" for vb.net). I didn't actually see a difference in testing, the regex worked both ways. – Eirik H Aug 19 '15 at 06:40
  • This fails for `C:/` (also with back slash). Fixed version: `^(?:[A-Z]\:|\.|(?:file\:\/\/|\\\\)[^\\\/\:\*\?\<\>\"\|]+)(?:(?:\\|\/)[^\\\/\:\*\?\<\>\"\|]+)*(?:\\|\/)?$`. This one works under the assumption that in the cases `\\name`, `C:\name`, and `file://name` for all occurences of `name` the same rules apply (i.e. `name` cannot contain any of the characters in `\/:*?<>"|`. – Good Night Nerd Pride Feb 25 '16 at 18:15
7

Try this one for Windows and Linux support: ((?:[a-zA-Z]\:){0,1}(?:[\\/][\w.]+){1,})

ryan
  • 71
  • 1
  • 1
4

I use this regex for capturing valid file/folder paths in windows (including UNCs and %variables%), with the exclusion of root paths like "C:\" or "\\serverName"

^(([a-zA-Z]:|\\\\\w[ \w\.]*)(\\\w[ \w\.]*|\\%[ \w\.]+%+)+|%[ \w\.]+%(\\\w[ \w\.]*|\\%[ \w\.]+%+)*)

this regex does not match leading spaces in path elements, so

  • "C:\program files" is matched
  • "C:\ pathWithLeadingSpace" is not matched

variables are allowed at any level

  • "%program files%" is matched
  • "C:\my path with inner spaces\%my var with inner spaces%" is matched
Federico Destefanis
  • 968
  • 1
  • 16
  • 27
2
regex CmdPrompt("^([A-Z]:[^\<\>\:\"\|\?\*]+)");

Basically we look for everything that's not in the list of forbidden Windows Path Characters:

< (less than)
> (greater than)
: (colon)
" (double quote)
| (vertical bar or pipe)
? (question mark)
* (asterisk)
Cocowalla
  • 13,822
  • 6
  • 66
  • 112
Bill
  • 21
  • 1
1

I know this is really old... but expanding on @agent-j's response I've added named groups, and support for period characters.

^(?<ParentPath>(?:[a-zA-Z]\:|\\\\[\w\s\.]+\\[\w\s\.$]+)\\(?:[\w\s\.]+\\)*)(?<BaseName>[\w\s\.]*?)$

I've saved this at Regexr

rbleattler
  • 334
  • 2
  • 11
0

I found most of the answers here to be a little hit or miss.

Found a good solution here though:

https://social.msdn.microsoft.com/forums/vstudio/en-US/31d2bc84-c948-4914-8a9d-97b9e788b341/validate-a-network-folder-path

Note* - this is only for network shares - not local files

Answer:

string pattern = @"^\\{2}[\w-]+(\\{1}(([\w-][\w-\s]*[\w-]+[$$]?)|([\w-][$$]?$)))+";
string[] names = { @"\\my-network\somelocation", @"\\my-network\\somelocation", 
    @"\\\my-network\somelocation", @"my-network\somelocation",
     @"\\my-network\\somelocation",@"\\my-network\somelocation\aa\dd",
     @"\\my-network\somelocation\",@"\\my-network\\somelocation"};
foreach (string name in names)
{
 if (Regex.IsMatch(name, pattern))
 {
  Console.WriteLine(name);
   //Directory.Exists function to check if file exists
 }
}   
Steve
  • 976
  • 12
  • 12
0

Alexander's Answer + Relative Paths

Alexander has the most correct answer thus far since it supports spaces in file names (i.e. C:\Program Files (x86)\ will match)... This aims to include relative paths as well.

For example, you can do cd / or cd \ and it does the same thing.

Further more, if you're currently in C:\some\path\to\some\place and you type either of those commands, you end up at C:\

Even more, you should consider paths, that start with '/' as a root path (to the current drive).

(?:[a-zA-Z]:(\|/)|file://|\\|.(/|\)|/)([^,\/:*\?\<>\"\|]+(\|/){0,1})

A Modified version of Alexander's answer, however, we include paths that are relative with no leading / or drive letter, as well as / with no leading drive letter (relative to the current drive as root).

Decoded
  • 1,057
  • 13
  • 17
  • This would validate unvalid file paths as: \\, \\\, C:\a\\ and it doesn't validate these: C:, C:\folder.something, C:\.folder: https://regex101.com/r/7UgtQA/2/tests – raythurnevoid Feb 06 '17 at 09:23