XML是一种结构化的标记语言,通常用于数据交换和配置文件存储,很多场景下我们需要从XML文本中提取特定内容,正则表达式作为一种文本匹配工具,也可以用于简单的XML内容解析,不过需要注意其适用边界。

正则解析XML的适用场景
正则解析XML仅适合处理结构简单、格式固定、没有嵌套标签或者嵌套层级非常明确的XML片段,比如以下这类简单的配置项XML:
<config>
<name>test_app</name>
<version>1.0.0</version>
<port>8080</port>
</config>
如果XML存在多层嵌套、标签属性、注释、CDATA块等复杂结构,正则解析很容易出现匹配错误,这类场景建议使用专业的XML解析器处理。
正则解析XML的核心思路
正则解析XML的核心是通过正则表达式匹配目标标签的开始标签、结束标签以及中间的文本内容,通用的匹配模式可以参考以下结构:
匹配单标签内容的正则:<标签名>([sS]*?)</标签名>,其中[sS]*?表示非贪婪匹配任意字符,避免跨标签匹配。
如果标签存在属性,需要先匹配开始标签的完整结构,比如<标签名s+[^>]*>用来匹配带属性的开始标签。
不同语言的正则解析XML示例
Python实现示例
以下是使用Python正则提取上述config XML中name和version内容的代码:
import re
xml_content = '''<config>
<name>test_app</name>
<version>1.0.0</version>
<port>8080</port>
</config>'''
# 提取name标签内容
name_pattern = r'<name>([sS]*?)</name>'
name_match = re.search(name_pattern, xml_content)
if name_match:
print("name内容:", name_match.group(1).strip())
# 提取version标签内容
version_pattern = r'<version>([sS]*?)</version>'
version_match = re.search(version_pattern, xml_content)
if version_match:
print("version内容:", version_match.group(1).strip())
Java实现示例
以下是Java中使用正则提取同样XML内容的代码:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class XmlRegexParse {
public static void main(String[] args) {
String xmlContent = "<config>n" +
" <name>test_app</name>n" +
" <version>1.0.0</version>n" +
" <port>8080</port>n" +
"</config>";
// 提取name标签内容
Pattern namePattern = Pattern.compile("<name>([\s\S]*?)</name>");
Matcher nameMatcher = namePattern.matcher(xmlContent);
if (nameMatcher.find()) {
System.out.println("name内容: " + nameMatcher.group(1).trim());
}
// 提取version标签内容
Pattern versionPattern = Pattern.compile("<version>([\s\S]*?)</version>");
Matcher versionMatcher = versionPattern.matcher(xmlContent);
if (versionMatcher.find()) {
System.out.println("version内容: " + versionMatcher.group(1).trim());
}
}
}
正则解析XML的注意事项
- 必须使用非贪婪匹配模式,否则会匹配到多个标签之间的所有内容,导致结果错误
- 如果XML中有换行、空格等空白字符,需要对匹配结果做trim处理,去除多余的空白
- 不要尝试用正则解析多层嵌套的XML,比如<a><b>content</b></a>这类结构,正则无法准确判断嵌套层级
- 如果XML中包含CDATA块,正则匹配需要额外处理
<![CDATA[和]]>的边界,否则会匹配到CDATA的标记内容
正则解析与专业XML解析器的选择
如果处理的XML结构简单、内容固定,且只是临时提取少量内容,正则解析可以快速实现需求,不需要引入额外的解析库。如果XML结构复杂、需要频繁处理,或者需要校验XML格式的合法性,建议使用专业的XML解析器,比如Python的xml.etree.ElementTree、Java的DOM或者SAX解析器,这类工具可以准确处理嵌套、属性、命名空间等XML特性,避免解析错误。