Шаблон регулярного выражения для анализа пути с помощью вкладок и новых строк? - PullRequest
0 голосов
/ 08 марта 2019

У меня есть путь dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext, который я хочу обрабатывать по одному сегменту за раз.Для каждого сегмента я хочу знать, сколько вкладок предшествует ему, и я хочу, чтобы оставшаяся часть пути оставалась нетронутой.Для данного примера

Итерация 1:

Preceding tabs: 0
Segment: dir
Rest: \n\tsubdir1\n\tsubdir2\n\t\tfile.ext

Итерация 2:

Preceding tabs: 1
Segment: subdir1
Rest: \n\tsubdir2\n\t\tfile.ext

Итерация3:

Preceding tabs: 1
Segment: subdir2
Rest: \n\t\tfile.ext

Итерация 4:

Preceding tabs: 2
Segment: file.ext
Rest: ""

Шаблон, который я придумал, - ((?<=\\R)\\h*)(\\H+).Тем не менее, это дает мне \tsubdir1\n в качестве первого матча.Что я делаю не так?

1 Ответ

1 голос
/ 08 марта 2019

Поскольку все разделы разделены разделителем строк \n, вы можете просто использовать .+, чтобы сопоставить их, поскольку по умолчанию точка . не может соответствовать разделителям строк, поэтому вы уверены, что она остановится до \n(или любой другой разделитель строк, например \r).

Вы также можете добавить несколько групп для отделения вкладок от фактического сегмента, например именованная группа (?<tabs>\t*), чтобы соответствовать нулю или нескольким вкладкам в начале каждого совпадения.

Чтобы напечатать остаток текста после совпадения, просто подстрока после индекса последнего сопоставленного символа (вы можете получить его через Matcher#end).

Для печати строки, которая будет содержать \n и \t (не как литералы, а как пара обратной косой черты и буквы) вы можете либо вручную заменить каждый "\n" на "\\n" и "\t" на "\\t", либо использовать служебный класс, такой как StringEscapeUtils из org.apache.commons.lang, который содержит escapeJava метод, который делает это для нас.

Таким образом, ваш код может выглядеть следующим образом:

String path = "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext";
Pattern p = Pattern.compile("(?<tabs>\t*)(?<segment>.+)");//dot can't match line separators
Matcher m = p.matcher(path);
int i = 1;
while(m.find()){
    System.out.println("iteration: " + i++);
    System.out.println("Preceding tabs: " + (m.group("tabs").length()));
    System.out.println("Segment: " + m.group("segment"));
    System.out.println("Rest: "+ StringEscapeUtils.escapeJava(path.substring(m.end())));
    System.out.println();
}

Вывод:

iteration: 1
Preceding tabs: 0
Segment: dir
Rest: \n\tsubdir1\n\tsubdir2\n\t\tfile.ext

iteration: 2
Preceding tabs: 1
Segment: subdir1
Rest: \n\tsubdir2\n\t\tfile.ext

iteration: 3
Preceding tabs: 1
Segment: subdir2
Rest: \n\t\tfile.ext

iteration: 4
Preceding tabs: 2
Segment: file.ext
Rest: 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...