使用制表符和换行符解析路径的正则表达式模式?
Regex pattern to parse path with tabs and newlines?
我有一个路径 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
作为第一场比赛。我做错了什么?
由于所有部分都由行分隔符分隔 \n
你可以简单地使用 .+
来匹配它们,因为默认情况下点 .
不能匹配行分隔符,所以你确定它会在 \n
(或任何其他行分隔符,如 \r
)之前停止。
您还可以添加一些组以将制表符与实际段分开,例如 named group (?<tabs>\t*)
以在每次匹配开始时匹配零个或多个制表符。
要在匹配后打印剩余文本,只需在最后一个匹配字符的索引后添加子字符串(您可以通过 Matcher#end
获取)。
要打印包含 \n
和 \t
的字符串(不是文字而是一对反斜杠和字母),您可以手动将每个 "\n"
替换为 "\n"
和 "\t"
与 "\t"
或使用实用程序 class,例如 org.apache.commons.lang
中的 StringEscapeUtils
,其中包含 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:
我有一个路径 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
作为第一场比赛。我做错了什么?
由于所有部分都由行分隔符分隔 \n
你可以简单地使用 .+
来匹配它们,因为默认情况下点 .
不能匹配行分隔符,所以你确定它会在 \n
(或任何其他行分隔符,如 \r
)之前停止。
您还可以添加一些组以将制表符与实际段分开,例如 named group (?<tabs>\t*)
以在每次匹配开始时匹配零个或多个制表符。
要在匹配后打印剩余文本,只需在最后一个匹配字符的索引后添加子字符串(您可以通过 Matcher#end
获取)。
要打印包含 \n
和 \t
的字符串(不是文字而是一对反斜杠和字母),您可以手动将每个 "\n"
替换为 "\n"
和 "\t"
与 "\t"
或使用实用程序 class,例如 org.apache.commons.lang
中的 StringEscapeUtils
,其中包含 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: