sublime批量替换模板变量可行但需分语法构造正则:{{...}}用{{(1+)}},${...}用\${(1+)},[[...]]用[[(2+)]];跨行需开启“dot matches newline”或用[\s\s]*?,中文变量须utf-8 with bom或[一-龥]匹配,替换用$1引用并预览确认。} ↩] ↩

Sublime 里批量替换模板变量(比如 {{ user_name }}、${api_url}、[[ count ]])完全可行,但必须分清模板语法类型、转义层级和作用域边界——直接搜 {{.*}} 很可能跨行吞掉整段 HTML 或误伤注释里的类似结构。
怎么识别并匹配不同模板语法的变量占位符
不同模板引擎写法差异大,正则不能一招鲜。关键是先看清楚原始文本中变量的真实格式,再针对性构造表达式:
-
{{ user_name }}类(Django/Jinja/Handlebars):用\{\{([^}]+)\}\}匹配,注意{和}必须转义,[^}]+防止贪婪跨到下一个}} -
${api_url}类(ES6 模板字面量、Shell):用\$\{([^}]+)\},同样要转义$和{,[^}]+保证只捕获内部内容 -
[[ count ]]类(某些 CMS 或自定义模板):用\[\[([^]]+)\]\],方括号在字符类外需转义,[^]]+表示“非右中括号的任意字符” - 若变量名含点号或中划线(如
{{ user.profile.name }}),把[^}]+改成[^}]*更稳妥,避免因空格或换行中断匹配
替换时怎么保留变量名但改前缀或加函数调用
单纯删掉模板符号没意义,多数场景是要统一包裹、转义或注入上下文。这时必须用捕获组 + 引用:
- 把所有
{{ xxx }}改成{{ safe(xxx) }}:
查找:\{\{([^}]+)\}\}
替换:{{ safe($1) }} - 把
${url}全部加上协议前缀:
查找:\$\{([^}]+)\}
替换:${baseUrl + $1} - 把
[[ id ]]转成驼峰并加引号:
查找:\[\[([a-z]+)_([a-z])([a-z]*)\]\]
替换:"$1\U$2\E$3"(注意大小写转换仅在替换框生效,且\U/\E是 Sublime 特有语法)
为什么替换了却漏掉部分变量,或跨行失效
两个最常见原因:一是默认模式下 . 不匹配换行符,二是模板变量被拆在多行(如 {{ 在一行,user_name 在下一行,}} 在第三行):
- 解决跨行问题:开启正则面板左下角的
.matches newline 选项(图标是带\n的点),或改用[\s\S]替代.,例如\{\{([\s\S]*?)\}\} - 别依赖
.*?无脑匹配——它可能吞掉中间的}},必须用否定字符类(如[^}]*)锚定边界 - 如果文件是 UTF-8 无 BOM 编码,中文变量名(如
{{ 用户名 }})可能匹配失败;改用\{\{([^\}]*?)\}\}并确保文件编码为 UTF-8 with BOM,或用[一-龥]显式匹配汉字
怎么避免把字符串字面量或注释里的模板变量也替了
正则本身不区分语法上下文,"{{ name }}" 和 {{ name }} 会被同等对待。这不是 bug,是设计限制:
- 最有效的方法是缩小作用域:先选中模板区域(比如整个
<template></template>块或{% block content %}内容),再按Ctrl+H替换,这样不会波及 JS 字符串或 Python 注释 - 如果必须全局操作,可加前置断言排除引号包围的情况:
(? ——但注意 Sublime 的 Boost.Regex 不支持 <code>(? 负向先行断言,得换思路:先用 <code>Ctrl+Shift+F搜索"\{\{.*?\}\}"手动确认哪些是字符串,再临时注释掉它们 - 执行前务必点
Find All,看底部面板列出的所有匹配项是否都符合预期;高亮太多?加^或$锚定行首行尾,或用\b限定单词边界
真正麻烦的不是写对正则,而是确认每处匹配都处在你认为“该被替换”的语境里——比如 {{ title }} 在 HTML 标签属性里、在 JS 字符串里、在 Vue 的 v-bind: 指令里,行为完全不同。别省那几秒预览时间,Find All 看一遍,比重开 Git 恢复快得多。











