模式与子组匹配时出错 - 贪婪或不合格的限定符都不起作用

时间:2015-05-13 12:27:58

标签: regex regex-group regex-greedy

我正在尝试将单词文档中的文本和前缀/后缀分开。这是一个ZIP文件,我参与word/document.xml看起来像

^.*<w:body> 
...this is the text... 
<w:sectPr[^>]*><some_selfclosing_tags/>*</w:sectPr>
</w:body>.*$

问题在于我无法确定要将可选

的模式引擎
 <w:sectPr>...</<w:sectPr> 

在带有</w:body>的后缀组中。 它既不适用于贪婪的?也不适用于不合格的??限定符,如下所示:

Pattern.compile("^(.*<w:body[^>]*>)(.*)"
+"((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>)?"
+"\\s*</w:body\\s*>.*)$", Pattern.DOTALL)

Pattern.compile("^(.*<w:body[^>]*>)(.*)"
+"((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>)??"
+"\\s*</w:body\\s*>.*)$", Pattern.DOTALL)

以下是该问题的简化版本:

String doc="<?xml version=\"1.0\"><w:document><w:body> ...text... <w:sectPr><w:cols w:space=\"720\"/></w:sectPr></w:body></w:document>";
Pattern rxv[]=new Pattern[]
        {Pattern.compile("^(.*<w:body[^>]*>)(.*)" 
                        +"((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>)?" 
                        +"\\s*</w:body\\s*>.*)$", Pattern.DOTALL)
        ,Pattern.compile("^(.*<w:body[^>]*>)(.*)" 
                        +"((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>)??" 
                        +"\\s*</w:body\\s*>.*)$", Pattern.DOTALL)
        };
ApplStr.ckRx(doc, rxv); 

以上产量在System.out上:

rx0:^(.*<w:body[^>]*>)(.*)((?:w:sectPr[^>]*>\s*(?:<\w+[^/>]*/>\s*)*</w:sectPr\s*>)?\s*</w:body\s*>.*)$
rx0Grp0:
<?xml version="1.0"><w:document><w:body> ...text... <w:sectPr><w:cols w:space="720"/></w:sectPr></w:body></w:document>
rx0Grp1:
<?xml version="1.0"><w:document><w:body>
rx0Grp2:
 ...text... <w:sectPr><w:cols w:space="720"/></w:sectPr>
rx0Grp3:
</w:body></w:document>

rx1:^(.*<w:body[^>]*>)(.*)((?:<w:sectPr[^>]*>\s*(?:<\w+[^/>]*/>\s*)*</w:sectPr\s*>)??\s*</w:body\s*>.*)$
rx1Grp0:
<?xml version="1.0"><w:document><w:body> ...text... <w:sectPr><w:cols w:space="720"/></w:sectPr></w:body></w:document>
rx1Grp1:
<?xml version="1.0"><w:document><w:body>
rx1Grp2:
 ...text... <w:sectPr><w:cols w:space="720"/></w:sectPr>
rx1Grp3:
</w:body></w:document>

我想要的是<w:sectPr><w:cols w:space="720"/></w:sectPr>在第3组而非第2组。

1 个答案:

答案 0 :(得分:0)

为了捕获组2中所需的子字符串,您需要在组2中使用.*?的惰性匹配:

^(.*<w:body[^>]*>)(.*?)((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>‌)?\\s*</w:body\\s*>.*)$

这是IDEONE demo

String str = "<?xml version=\"1.0\"><w:document><w:body> ...text... <w:sectPr><w:cols w:space=\"720\"/></w:sectPr></w:body></w:document>";
String rx = "^(.*<w:body[^>]*>)(.*?)((?:<w:sectPr[^>]*>\\s*(?:<\\w+[^/>]*/>\\s*)*</w:sectPr\\s*>)?\\s*</w:body\\s*>.*)$";
Pattern ptrn = Pattern.compile(rx);
Matcher m = ptrn.matcher(str);
while (m.find()) {
    System.out.println(m.group(1));
    System.out.println(m.group(2));
    System.out.println(m.group(3));
}

输出:

<?xml version="1.0"><w:document><w:body>
 ...text... 
<w:sectPr><w:cols w:space="720"/></w:sectPr></w:body></w:document>