I need to check, if a Windows folder name is potentially valid. The folder does not neccessarily exist already. It can be an absolute path, a relative one, or it can be located on another machine in the network (addressed via UNC).
The following are valid locations:
[[X:]\] 'Including an empty string.
\\server name\ 'Including \\123.123.123.123\
Note, that Windows does accept /
instead of \
as well (to verify, enter C:/Users
in the file explorer).
The location can be followed by a deep path, and must terminate in a path name with or without an ending slash:
[folder name\]*folder name[\]
None of the characters /\:*?<>"|
may appear within server names or folder names.
This can be done by matching the provided text against a regular expression. Thus I created a such:
^ 'At the beginning of the string must appear
( 'either
\\{2} '2 backslashes
[^/\\\:\*\?\<\>\|]+ 'followed by a server name
(\\|/) 'and a slash,
| 'or
( 'a sequence of
(\.{2}) '2 dots
(\\|/) 'followed by a slash
)+ 'which may occur at least one time
| 'or
[A-Za-z] 'a drive letter
\: 'followed by a colon
(\\|/) 'and a slash
| 'or
(\\|/) 'simply a slash
)? 'or nothing at all;
( 'followed by a sequence of
[^/\\\:\*\?\<\>\|]+ 'a folder name
(\\|/) 'followed by a slash
)* 'which may occur multiple times
[^/\\\:\*\?\<\>\|]+ 'The last folder needs no final slash
(\\|/)? 'but may have one.
The following function is called:
Private Function IsDirValid(sFile As String) As Boolean
Dim sPattern As String = "^[^/\\\:\*\?\<\>\|]+(\\|/)" &
"|((\.{2})(\\|/))+" &
"|[A-Za-z]\:(\\|/)" &
"|(\\|/)" &
")?" &
"([^/\\\:\*\?\<\>\|]+(\\|/))*" &
"[^/\\\:\*\?\<\>\|]+(\\|/)?"
Dim oMatch As Match = Regex.Match(sFile, sPattern)
'Debug.Print("""" & sFile & """ returns """ & oMatch.Value & """")
Return (sFile = oMatch.Value)
End Function
which seems to work not too bad. These expressions all are recognized as valid:
path name[/]
path name/path name/path name[/]
/path name[/]
/path name/path name/path name[/]
../../path name[/]
../../path name/path name/path name[/]
c:/path name[/]
c:/path name/path name/path name/file name[/]
\\server name/path name[/]
\\server name\path name\path name\path name[/]
(Did I miss some?)
My only problem is now, that each path name
does allow leading and trailing whitespace. This is not allowed in path names. However, "in-name" blanks are allowed.
Of course, I could replace the 3 occurrences of
[^/\\\:\*\?\<\>\|]+
by
[^/\\\:\*\?\<\>\|\ ][^/\\\:\*\?\<\>\|]*[^/\\\:\*\?\<\>\|\ ]
which would solve the whitespace problem (tested), but introduces another one: the names need to be at least 2 characters long now (unacceptable of course). And it's becoming ugly.
Alas, in the regex quick reference guide I was not able to find a suitable quantifier for my problem.
Thence: is there a more concise way?