sublime text 用正则匹配xml标签而非解析语法树,需启用(?s)跨行、非贪婪.*?、正确捕获组才能精准提取内容,否则易漏匹配或误吞标签。

Sublime Text 本身不解析 XML 语法树,所谓“解析并重构”实际是靠正则匹配标签边界 + 捕获内容 + 安全替换完成的。它不能验证嵌套、不处理 CDATA、不识别命名空间,但对结构清晰、无嵌套的配置类 XML(如 RSS、Android manifest、简单 RSS feed)足够高效。
为什么 title>[^ 匹配失败或漏内容
常见错误是直接抄写 HTML 正则到 XML 场景,忽略了 Sublime 的正则引擎限制和 XML 实际结构。
- 默认不跨行:
title>[^ 遇到换行就中断,必须显式启用跨行模式 [^ 无法匹配换行符,<code>[\s\S]在 Sublime 中不被支持,得用(?s)开启 dotall 模式- 未转义斜杠:
/title中的/不是元字符,但写成更安全,避免误判 - 贪婪匹配陷阱:
(?s)<title>.*</title>会从第一个<title></title>匹到最后一个,中间所有标签全吞掉
正确写法:(?s)<title>(.*?)</title> —— ? 让 .* 变成非贪婪,(?s) 让 . 匹配换行符。
Ctrl+H 替换时 $1 不展开,只输出字面 $1
这不是正则写错了,是三个基础条件没同时满足:
-
.*图标必须点亮(状态栏显示Regex),否则整个面板按普通字符串处理 - 查找框里的括号必须是字面意义的捕获组:想匹配
<node id="123"></node>中的 id 值,得写<node id="([^">,而不是 <code><node id=".*">(后者没括号,就没有 <code>$1) - 替换框只认
$1、$2,不支持\1或${1};$0表示整行匹配,可用于加前缀,比如xml_$0
验证方法:先点 Find All 看高亮是否精准;再点 Replace Preview(Ctrl+Shift+H),确认 $1 是否已展开为实际内容。
批量把 <item><title>A</title>
<link>B</item> 拆成独立字段行
这是典型的数据清洗需求,目标是把每个 <item></item> 块内的子标签内容提取为键值对格式,一行一个字段。
- 先用
(?s)<item>(.*?)</item>找到每个完整 item 块(注意非贪婪) - 再在该块内逐个提取:
<title>(.*?)</title>→ 替换为title: $1;<link>(.*?)→ 替换为link: $1 - 关键技巧:不要一次全换,而是分步操作——先
Find All选中所有<item></item>块,按Ctrl+Shift+Right(Win/Linux)扩展选中整个块,再对选区内部执行子标签替换 - 若需保留原始结构作对照,可在替换前先复制一份,或用
Ctrl+Shift+P→Copy as Plain Text导出原始匹配
最后补一刀:^\s*$ 删除空行(关闭 . matches newline),让结果干净紧凑。
真正麻烦的从来不是正则怎么写,而是 XML 标签里那些看不见的坑:属性值没引号、& 没转义、BOM 头残留——这些都会让后续任何解析逻辑失效。每次批量改之前,先用 python -c "import xml.etree.ElementTree as ET; ET.parse('test.xml')" 过一遍,比事后调试快十倍。











