9

Using JAVA. I am trying to find a more elegant way for validating a Linux folder path (not including the file name).

What I have so far is this: "^\\/$|^((\\/([a-zA-Z0-9_-]+))+)$"

Folder paths should include only following characters: letters, numbers, dashes or underscore.

Test cases

Valid/ matches:

  • /
  • /abc
  • /abc/abc/abc/abc

Invalid / not-matches:

  • null or empty string
  • /abc/
  • /abc/abc/abc/abc/
5
  • Well the elegant way would be to not use regex at all and instead use the nio libraries to determine if the path is valid.... Commented Mar 8, 2019 at 20:14
  • What is the use-case for your validation? Why is your RegEx not working for you? Maybe we can find a better solution besides using the RegEx :) Commented Mar 8, 2019 at 21:15
  • My pattern works, it just looks clunky, and wasn't sure I was doing it right. Commented Mar 8, 2019 at 21:26
  • Why are you limiting the folder names to alphanumeric? A folder name can contain close to any character. Commented Mar 9, 2019 at 10:28
  • Using only alphanumeric because of requirements in the application we are using. Commented Mar 10, 2019 at 13:07

3 Answers 3

7

Issue with your RegEx

Your supplied RegEx is working on the test-cases.

You could even reduce it by removing backslashes \\ and outer pair of parentheses. Begin ^ and end $ are only needed once (around the two alternatives).

Possible Solution using Regular Expression

You can test the RegEx on RegexPlanet.com (click on Java-Button for tests)

^/|(/[a-zA-Z0-9_-]+)+$

or equivalent (see demo on RegexPlanet)

^/|(/[\w-]+)+$

Explained: \w matches a word-character (same as [a-zA-Z0-9_], not matching the dash).

Implementation in Java code:

public boolean isValidLinuxDirectory(String path) {
    Pattern linuxDirectoryPattern = Pattern.compile("^/|(/[a-zA-Z0-9_-]+)+$");
     return path != null && !path.trim().isEmpty() && linuxDirectoryPattern.matcher( path ).matches();
}

Alternative Solution using File

Note the docs on isDirectory():

Returns: true if and only if the file denoted by this abstract pathname exists and is a directory; false otherwise

So it may only validate your requirements (valid Linux folder) if run on a Linux machine and if the folder/directory exists.

public boolean isValidExistingDirectory(String path) {
     if (path == null || path.trim().isEmpty()) return false;
     File file = new File( path );
     return file.isDirectory();
}

Extended Solution

As stated in comment the special form of root // should also be valid. Then use this RegEx:

^/|//|(/[\w-]+)+$

It supports:

  1. root-directory /
  2. special form of root-directory //
  3. any non-root directory, which name is composed out of alphas, numbers, dash or underscore (e.g. /abc/123/_abc-123)

See also

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a bunch! Very helpful!
^/|/[a-zA-Z0-9_-]+)+$ does not work for the case where the folder path is //. ^/$|^(/[a-zA-Z0-9_-]+)+$ works.
@afrey OK. Then please UPDATE your question for extended requirement (as I just did). Sure that your regex ^/$|^(/[a-zA-Z0-9_-]+)+$ does match the special-root (//) ??
1

Here ya go: \/[a-zA-Z0-9_\/-]*[^\/]$

EDIT

First character matches a forward slash /. The following character group matches a-z, A-Z, 0-9, underscores, forward slashes, and dashes (all accepted directory and filename characters). The following asterisk makes the pattern match that character group 0 or more times (so any combo of those characters). The last character group has a negation ^ meaning it matches anything EXCEPT what's in the character group, being the final forward slash that we don't want to match. Finally the $ to end the string.

2 Comments

Also if you can actually use the filesystem take a look at this
Great, but it doesn't accept "/" as a path. Here's an improvment: ^\/([a-zA-Z0-9_\/-]*[^\/])?$
0

To cover all cases including the root directory, you will need the following:

^\/$|(\/[a-zA-Z_0-9-]+)+$

See Regex Demo using global and multiline modifiers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.