RegEx跨越两行,仅在单独的行上匹配

时间:2016-04-17 10:15:47

标签: java regex

我有一个.rtf文件,里面有很多粗体标题。我试图在两个大胆的标题之间捕获数据。但是,用于说出某些内容的标记是粗体的,与文本的两端完全相同。

所以我试图找到将捕获下一个最近一行(以及其间的所有内容)而不是同一行上的粗体标记的模式。我正在使用Java。

示例文字:

\par }{\b\f1\fs24\ul\insrsid14762702 Data}{\insrsid14762702 \tab \tab }{\b\f1\fs24
\par Start:\tab 2015-01-14 10:56:25
\par Duration:\tab 22:40:23
\par Positions:\tab 3.0, 5.0, 7.0, 9.0, 15.0, 17.0 cm
\par Sensor Position(s):\tab -10.0, 5.0 cm
\par Depth:\tab N/A
\par 
\par }{\b\f1\fs24
\par }{\b\f1\fs24\ul\insrsid14762702 History}{\insrsid14762702 
\par Other 
{\b\f1\fs24\ul\insrsid14762702

我目前使用的是:

((\\\\b\\\\f1\\\\fs24.+?\\{\\\\b\\\\f1\\\\fs24))

整个Java系列是:

Pattern pattern = Pattern.compile("((\\\\b\\\\f1\\\\fs24.+?\\{\\\\b\\\\f1\\\\fs24))",Pattern.DOTALL);

哪位给了我:

\par }{\b\f1\fs24\ul\insrsid14762702 Data}{\insrsid14762702 \tab \tab }{\b\f1\fs24

\par }{\b\f1\fs24
    \par }{\b\f1\fs24

{\b\f1\fs24\ul\insrsid14762702 History}{\insrsid14762702 
    \par Other 
    {\b\f1\fs24

预期输出为:

\par }{\b\f1\fs24\ul\insrsid14762702 Data}{\insrsid14762702 \tab \tab }{\b\f1\fs24
    \par Start:\tab 2015-01-14 10:56:25
    \par Duration:\tab 22:40:23
    \par Positions:\tab 3.0, 5.0, 7.0, 9.0, 15.0, 17.0 cm
    \par Sensor Position(s):\tab -10.0, 5.0 cm
    \par Depth:\tab N/A
    \par 
    \par }{\b\f1\fs24

 \par }{\b\f1\fs24
    \par }{\b\f1\fs24

\par }{\b\f1\fs24\ul\insrsid14762702 History}{\insrsid14762702 
    \par Other 
    {\b\f1\fs24\ul\insrsid14762702

2 个答案:

答案 0 :(得分:1)

您可以使用2个捕获的组。一个用于启动标记和文本到结束标记(不应该在同一行上)。您需要一个前瞻才能匹配重叠匹配。第二个被捕获的小组将进入前瞻。

你可以使用正则表达式:

([^\n]*\Q{\b\f1\fs24\E[^\n]*\n.*?)(?=([^\n]*\Q{\b\f1\fs24\E))

RegEx Demo

PS:请注意使用Pattern.quote以避免过度转义。

<强>代码:

String text = "\\par }{\\b\\f1\\fs24\\ul\\insrsid14762702 Data}{\\insrsid14762702 \\tab \\tab }{\\b\\f1\\fs24\n\\par Start:\\tab 2015-01-14 10:56:25\n\\par Duration:\\tab 22:40:23\n\\par Positions:\\tab 3.0, 5.0, 7.0, 9.0, 15.0, 17.0 cm\n\\par Sensor Position(s):\\tab -10.0, 5.0 cm\n\\par Depth:\\tab N/A\n\\par \n\\par }{\\b\\f1\\fs24\n\\par }{\\b\\f1\\fs24\\ul\\insrsid14762702 History}{\\insrsid14762702 \n\\par Other \n{\\b\\f1\\fs24\\ul\\insrsid14762702";       
String tag = Pattern.quote("{\\b\\f1\\fs24");

Pattern p = Pattern.compile( "([^\n]*" + tag + "[^\n]*\n.*?)(?=([^\n]*" + tag + "))",
            Pattern.DOTALL );

Matcher m = p.matcher( text );

List<String> matches = new ArrayList<>();
while(m.find()) {
    matches.add(m.group(1) + m.group(2));
}

for (String s: matches)
    System.err.println(s + "\n");

<强>输出:

\par }{\b\f1\fs24\ul\insrsid14762702 Data}{\insrsid14762702 \tab \tab }{\b\f1\fs24
\par Start:\tab 2015-01-14 10:56:25
\par Duration:\tab 22:40:23
\par Positions:\tab 3.0, 5.0, 7.0, 9.0, 15.0, 17.0 cm
\par Sensor Position(s):\tab -10.0, 5.0 cm
\par Depth:\tab N/A
\par 
\par }{\b\f1\fs24

\par }{\b\f1\fs24
\par }{\b\f1\fs24

\par }{\b\f1\fs24\ul\insrsid14762702 History}{\insrsid14762702 
\par Other 
{\b\f1\fs24

答案 1 :(得分:1)

您需要多行正则表达式,如下所示:

 String text = "\\par }{\\b\\f1\\fs24\\ul\\insrsid14762702 Data}{\\insrsid14762702 \\tab \\tab }{\\b\\f1\\fs24\n" +
"\\par Start:\\tab 2015-01-14 10:56:25\n" +
"\\par Duration:\\tab 22:40:23\n" +
"\\par Positions:\\tab 3.0, 5.0, 7.0, 9.0, 15.0, 17.0 cm\n" +
"\\par Sensor Position(s):\\tab -10.0, 5.0 cm\n" +
"\\par Depth:\\tab N/A\n" +
"\\par \n" +
"\\par }{\\b\\f1\\fs24\n" +
"\\par }{\\b\\f1\\fs24\\ul\\insrsid14762702 History}{\\insrsid14762702 \n" +
"\\par Other \n" +
"{\\b\\f1\\fs24\\ul\\insrsid14762702";

Pattern pattern = Pattern.compile("(?mi)\\\\b(?<content>.*)\\\\b");
Matcher matcher =  pattern.matcher(text);

while(matcher.find()){
  String content = matcher.group("content");
  System.out.println("content: "+ content);
}