JavaScript中使用正则表达式解析并提取复杂模板字符串中的内容

JavaScript中使用正则表达式解析并提取复杂模板字符串中的内容
最新回答
哥特式·浅唱

2026-04-17 21:30:24

在JavaScript中,可使用正则表达式结合matchAll方法解析并提取复杂模板字符串内容,核心步骤如下:

  • 构建正则表达式使用正则表达式/{{s*([^}]+)s*}}|([^{}]+)/g匹配两类内容:

    模板标记:{{s*([^}]+)s*}}

    {{和}}:转义匹配字面量{{和}}。

    s*:匹配零个或多个空白字符(如空格、制表符)。

    ([^}]+):第一个捕获组,匹配{{和}}之间非}的字符(即变量名)。

    普通文本:([^{}]+)

    第二个捕获组,匹配非{和}的任意字符(即模板标记外的文本)。

    |:逻辑“或”,确保匹配模板标记或普通文本。

    /g:全局标志,匹配所有符合条件的子串。

  • 使用matchAll获取匹配结果String.prototype.matchAll()返回迭代器,包含所有匹配项的详细信息(如完整匹配、捕获组、索引等)。通过扩展运算符[...input.matchAll(regex)]将其转为数组。示例输出:

    [ ["{{ text1 }}", "text1", undefined, index: 0, ...], [" 123 ", undefined, " 123 ", index: 14, ...], ...]

    match[0]:完整匹配字符串(如{{ text1 }}或123)。

    match[1]:若匹配模板标记,则存储变量名(如text1);否则为undefined。

    match[2]:若匹配普通文本,则存储文本内容(如123);否则为undefined。

  • 后处理匹配结果通过map操作根据捕获组类型处理匹配项:

    模板标记:若match[1]存在,提取变量名并去除首尾空格,重新封装为{{变量名}}。if (match[1] !== undefined) { return `{{${match[1].trim()}}}`; // 输出如"{{text1}}"}

    普通文本:若match[2]存在,直接返回原始文本(保留空格)。else if (match[2] !== undefined) { return match[2]; // 输出如" 123 "}

    过滤空值:使用filter(Boolean)移除可能的空字符串(如连续分隔符导致的空匹配)。

  • 完整代码示例

    const input = `{{ text1 }} 123 {{text1}}{{text1}} {{ text1}}134`;const regex = /{{s*([^}]+)s*}}|([^{}]+)/g;const result = [...input.matchAll(regex)] .map(match => { if (match[1] !== undefined) { return `{{${match[1].trim()}}}`; } else if (match[2] !== undefined) { return match[2]; } return match[0]; }) .filter(Boolean);console.log(result); // 输出: ["{{text1}}", " 123 ", "{{text1}}", "{{text1}}", " ", "{{text1}}", "134"]
  • 注意事项与优化

    变量名规范:若需限制变量名格式(如仅允许字母、数字、下划线),可将([^}]+)替换为([wd_]+)。

    性能优化:对于长字符串或高频调用,需测试正则表达式性能;必要时拆分逻辑或使用更高效的解析方法。

    错误处理:当前正则将不完整的{{或}}视为普通文本,若需严格校验格式,需增强正则或添加额外逻辑。

    复杂场景:对于嵌套模板或条件逻辑,建议使用专用模板引擎(如Handlebars、EJS)。

总结:通过正则表达式的“或”操作符和捕获组,结合matchAll的全局匹配能力,可高效解析复杂模板字符串。后处理阶段根据匹配类型精细化处理内容,既能提取模板变量,又能保留原始文本格式,满足多样化需求。