Поскольку все разделы разделены разделителем строк \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: