Reputation: 1175
I want to create a regex to split a path as shown in the following scheme:
Path: c:\foo\bar\baz.txt
Root name: c:
Parent path: c:\foo\bar
Filename: baz.txt
Stem: baz
Extension: txt
Here is what I have. The problem is that it doesn't work when I have a filename without an extension:
^(([aA-zZ]:)\\(?:[^:]+))\\(([^\\]+)\.([^\.]+))$
I can change it to
^(([aA-zZ]:)\\(?:[^:]+))\\(([^\\]+)(\.([^\.]+))?)$
but it doesn't split a filename to a stem and an extension.
Upvotes: 3
Views: 4685
Reputation: 785186
You may use this regex with a lazy quantifier and an optional group:
^(([a-zA-Z]:)(?:\\[^:]+)?)\\(([^\\\n]+?)(?:\.([^.\n]+))?)$
It is important to make ([^\\]+?)
a lazy match to avoid it matching too much when next non-capture group i.e. (?:\.([^.\n]+))?
is an optional match.
Upvotes: 3
Reputation: 4049
A possible solution to split your path is to use regex group (Demo here):
Regex explanation with 'c:\foo\bar\baz.txt'
:
(?<drive>[a-z]:)
-> 'c:'
(?<file>(?<fname>\\w+)(?:\.(?<fext>\w+))?)
(?<fname>\\w+)
-> 'baz'
(?<fext>\\w+)
-> 'txt'
drive
+ a repetion of \\\w+\\?
:
(?<ppath>(?<drive>[a-z]:)(?:\\\w+\\?)+)
So the full path is drive + parent path + file
:
(?<fullpath>(?<ppath>(?<drive>[a-z]:)(?:\\\w+\\?)+)(?<file>(?<fname>\w+)(?:\.(?<fext>\w+))?)$)
// Example without group
const path = 'c:\\foo\\bar\\baz.txt';
const regex = /([a-z]:)((?:\\?\w+\\)+)((\w+)(?:\.(\w+))?)/;
const found = path.match(regex);
// console.log(found); // Array ["c:\foo\bar\baz.txt", "c:", "\foo\bar\", "baz.txt", "baz", "txt"]
console.log('Root name:\t' + found[1]); // drive
console.log('Parent path:\t' + found[1]+found[2]); // Parent path
console.log('Filename:\t' + found[3]); // File name
console.log('Stem:\t\t' + found[4]); // Stem
console.log('Extension:\t' + found[5]); // Extension
// Java example with group
String s = "c:\\foo\\bar\\baz.txt";
Pattern p = Pattern.compile("(?<fullpath>(?<ppath>(?<drive>[a-z]:)(?:\\\\\\w+\\\\?)+)(?<file>(?<fname>\\w+)(?:\\.(?<fext>\\w+))?)$)");
Matcher m = p.matcher(s);
while (m.find()) {
System.out.println("Path:\t\t" + m.group("fullpath"));
System.out.println("Root name:\t" + m.group("drive"));
System.out.println("Parent path:\t" + m.group("ppath"));
System.out.println("Filename:\t" + m.group("file"));
System.out.println("Stem:\t\t" + m.group("fname"));
System.out.println("Extension:\t" + m.group("fext"));
}
/* OUTPUT */
Path: c:\foo\bar\baz.txt
Root name: c:
Parent path: c:\foo\bar\
Filename: baz.txt
Stem: baz
Extension: txt
Upvotes: 3