Regex to extract path from file

Viewed 154

I'm trying to build a regexp or string split/replace that will return the filepath with the following tests

let filepath_1 = "./path/to/file.js";     // ./path/to/
let filepath_2 = "./path/to/file.min.js"; // ./path/to/
let filepath_3 = "./path/to/";            // ./path/to/
let filepath_4 = "./path/to";             // ./path/to
let filepath_5 = "/path/to";              // /path/to
let filepath_6 = "path/to";               // path/to 

The slashes in the final results don't really matter, as long as the file is gone from the results and that it doesn't think that to is a file name..

My best effort so far is using file.replace(/[^\/]*$/, "") but it will remove the to in /path/to. I need some logic about the "." character

3 Answers

You can use the following to replace what you do not need based on the examples above (that is, if you just need to remove the file names at the end of the path):

.replace(/[^\/]+\.\w+$/, '')

See the regex demo. The regex will match one or more chars other than a / (with [^\/]+), then a . (with \.) and then any one or more word chars (\w+) at the end of the string ($).

You can use the following to extract what you need:

/^(?:\.*\/)?[^\/]+\/[^\/]+\/?/

See the regex demo. Details:

  • ^ - start of string
  • (?:\.*\/)? - an optional sequence of zero or more . chars followed with a /
  • [^\/]+ - zero or more chars other than /
  • \/ - a / char
  • [^\/]+ - zero or more chars other than /
  • \/? - an optional / char

See the JavaScript demo:

let filepath_1 = "./path/to/file.js";     // ./path/to/
let filepath_2 = "./path/to/file.min.js"; // ./path/to/
let filepath_3 = "./path/to/";            // ./path/to/
let filepath_4 = "./path/to";             // ./path/to
let filepath_5 = "/path/to";              // /path/to
let filepath_6 = "path/to";               // path/to 
const arr = [filepath_1, filepath_2, filepath_3, filepath_4, filepath_5, filepath_6];
// Replacing
const reg = /[^\/]+\.\w+$/;
arr.forEach( x => console.log(x, "=>", x.replace(reg, '')) )
// Matching
const regex = /^(?:\.*\/)?[^\/]+\/[^\/]+\/?/g;
arr.forEach( x => console.log(x, "=>", x.match(regex)?.[0]) )

Regex may not produce the most readable solution in this case since there is an if/then implicitly. What about a simple split?

p = ["./path/to/file.js", "./path/to/file.min.js", "./path/to/", "./path/to", "/path/to", "path/to"]
output = p.map(s => {

  // Begin
  a = s.split("/")
  if (a[a.length - 1].includes(".")) {
    a.pop()
    return a.join("/") + "/"
  }
  return a.join("/")
  // End

})

console.log("output", output)

Related