Java使用Pattern Matcher移除XML标签内容正则匹配失效问题
Java正则匹配XML指定标签内容失败问题排查与修正
你的代码无法得到预期匹配结果,是正则编写存在以下几处明确错误:
- 标签名拼写错误:目标处理指令标签为
<?insert_start ?>、<?insert_end ?>,正则中误写为oxy_insert_start、oxy_insert_end,名称完全不匹配,无法定位到目标片段。 - 特殊字符未转义:
?在正则语法中是代表「匹配前一个字符0次或1次」的特殊量词,要匹配XML标签里的字面问号,必须用反斜杠转义写为\?,否则正则对<?的解析逻辑会完全偏离预期。 - 缺少跨行匹配模式:待匹配的标签内容包含换行符,Java正则默认模式下
.不会匹配换行符,会导致跨多行的内容匹配中断,必须给Pattern添加Pattern.DOTALL参数,让.可以匹配包括换行在内的所有字符。 - 内层匹配规则有误:一是reference标签匹配的正则结尾多写了一个右尖括号(写为
</reference>>,实际文本只有一个>);二是示例文本中第二个reference标签是不规范的未闭合写法<reference>,原正则只匹配闭合的</reference>,会漏匹配;三是内层正则同样未开启DOTALL模式,无法匹配跨行的reference内容。
修正后可运行代码
import java.util.regex.Matcher; import java.util.regex.Pattern; public class XmlTagParser { public static void main(String[] arg) { String strXmlTxt = "<?insert_start author=\"0017598\" timestamp=\"20220704T111051+0530\"?>\r\n" + "<reference id=\"\">Yoon et al., 2014L.W.YoonT.N.AngG.C.NgohA.S.M.ChuaFungal solid-state fermentation and various methods of enhancement in cellulase productionBiomass Bioenergy672014319338Yoon, L. W., Ang, T. N., Ngoh, G. C., Chua, A. S. M., 2014. Fungal solid-state fermentation and various methods of enhancement in cellulase production.Biomass Bioenergy.67, 319-338.</label/></reference>\r\n" + "<reference id=\"\">Xue et al., 2015Y.P.XueM.JinA.OrjuelaP.J.SliningerB.S.DienB.E.DaleV.BalanMicrobial lipid production from AFEX™ pretreated corn stoverRSC Adv.520152872528734Xue, Y. P., Jin, M., Orjuela, A., Slininger, P. J., Dien, B. S., Dale, B. E., Balan, V., 2015. Microbial lipid production from AFEX™ pretreated corn stover.RSC adv.5, 28725-28734.<label/><reference>\r\n" + "<?insert_end?>"; System.out.println("原始文本:\n" + strXmlTxt); // 外层正则:修正标签名、转义特殊字符、开启DOTALL跨行匹配 Pattern correctionRegexp = Pattern.compile( "<\\?insert_start author=\"(.*?)\" timestamp=\"(.*?)\"\\?>(.*?)<\\?insert_end\\?>", Pattern.DOTALL ); Matcher correctionMatcher = correctionRegexp.matcher(strXmlTxt); while (correctionMatcher.find()) { String correctionTag = correctionMatcher.group(); System.out.println("\n=== 匹配到的insert包裹块 ==="); System.out.println(correctionTag); // 内层正则:去掉多余尖括号、兼容不规范reference标签、开启跨行匹配 Pattern refTagRegex = Pattern.compile( "<reference id=\"\">(.*?)<label/?>(</reference>|<reference>)", Pattern.DOTALL ); Matcher refTagMatcher = refTagRegex.matcher(correctionTag); while (refTagMatcher.find()) { String refContent = refTagMatcher.group(1); System.out.println("\n提取到的reference内容:\n" + refContent); } } } }
补充提示:正则仅适合处理结构固定、无复杂嵌套的简单XML场景,如果后续XML存在标签嵌套、格式变动等情况,优先使用DOM/StAX等正规XML解析器处理,避免正则出现误匹配、漏匹配问题。
内容的提问来源于stack exchange,提问作者Pavithra Sudhakaran
相关产品推荐
相关产品推荐

