Регулярное выражение для разделения пути к файлу - PullRequest
2 голосов
/ 20 апреля 2020

Я хочу создать регулярное выражение для разделения пути, как показано на следующей схеме:

Path:        c:\foo\bar\baz.txt
Root name:   c:
Parent path: c:\foo\bar
Filename:    baz.txt
Stem:        baz
Extension:   txt

Вот что у меня есть. Проблема в том, что это не работает, когда у меня есть имя файла без расширения:

^(([aA-zZ]:)\\(?:[^:]+))\\(([^\\]+)\.([^\.]+))$

Я могу изменить его на

^(([aA-zZ]:)\\(?:[^:]+))\\(([^\\]+)(\.([^\.]+))?)$

, но оно не разделяет имя файла на стебель и расширение.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2020

Возможным решением для разделения вашего пути является использование группы регулярных выражений ( Демо здесь ):

Объяснение регулярных выражений с помощью 'c:\foo\bar\baz.txt':

  • Первый вещь - это диск: (?<drive>[a-z]:) -> 'c:'
  • Последнее - это файл: (?<file>(?<fname>\\w+)(?:\.(?<fext>\w+))?)
    • (?<fname>\\w+) -> 'baz'
    • (?<fext>\\w+) -> 'txt'
  • Тогда родительский путь будет drive + повторение \\\w+\\?: (?<ppath>(?<drive>[a-z]:)(?:\\\w+\\?)+)

Таким образом, полный путь 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
2 голосов
/ 20 апреля 2020

Вы можете использовать это регулярное выражение с ленивым квантификатором и необязательной группой:

^(([a-zA-Z]:)(?:\\[^:]+)?)\\(([^\\\n]+?)(?:\.([^.\n]+))?)$

Демонстрация RegEx

Важно сделать ([^\\]+?) ленивым совпадение, чтобы избежать слишком большого совпадения, когда следующая группа без захвата, т.е. (?:\.([^.\n]+))? является необязательным совпадением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...