JavaScript 正则表达式多行匹配与动态替换教程

6次阅读

JavaScript 正则表达式多行匹配与动态替换教程

本文详解如何使用 javascript 的 `String.prototype.replace()` 配合回调函数,精准匹配多行属性块(如 `@#@ … @#@` 包裹内容),并将其动态转换为多个 `{% set … %}` 模板语句。

前端模板预处理或构建时,常需将自定义标记语法(如 @#@ attr=”val” class=”foo” @#@)转换为目标模板引擎(如 Nunjucks)可识别的语法。直接用正则捕获整个属性块后进行结构化解析,是高效且可控的方案。

核心思路是:用正则匹配 @#@ 包裹的任意属性字符串 → 在 replace 的回调函数中解析该字符串 → 拆分每个 key=”value” 对 → 逐个生成 {% set key=”value” %} 语句

以下是完整、健壮的实现代码:

function convertAtHashBlocks(content) {   const regex = /@#@s*([sS]*?)s*@#@/gim; // 使用 [sS] 真正匹配多行(替代 . 不跨行缺陷)    return content.replace(regex, (match, attrsBlock) => {     // 按双引号结尾 + 可选空白符分割(支持换行、缩进)     const attrPairs = attrsBlock       .trim()       .split(/"s+/g)       .filter(str => str.trim() !== '');      return attrPairs       .map(pair => {         // 安全提取 key="value" 格式:允许 value 中含空格,但必须以 " 结尾         const kvMatch = pair.match(/^([^=]+)=(".*?"|'.*?'|[^'"s]+)/);         if (!kvMatch) return `{% set ${pair.trim()}" %}`; // 降级兜底          const [, key, value] = kvMatch;         return `{% set ${key.trim()}=${value} %}`;       })       .join('n');   }); }  // ✅ 使用示例 const input = `@#@ visibility="hidden" @#@ {% include "grid-overlay.njk" %}  @#@ contentPartial="promo/tru-report/" class="tuc-19bc10f7-e41518-0 q-promo-container promo--hidden tuc-19bc10f7-e41518-0" expires="2023-04-30T17:00:00Z"@#@ {% include "promo-banner.njk" %}`;  console.log(convertAtHashBlocks(input));

⚠️ 关键注意事项

立即学习Java免费学习笔记(深入)”;

  • 原正则 ([a-zA-Z0-9-_/.=:”‘s]+) 存在严重缺陷:. 在字符类中不表示“任意字符”,且未支持换行;应改用 [sS] 或 [^]* 实现真正多行捕获;
  • split(/”s+/g) 依赖引号后紧跟空白作为分隔,对紧凑格式(如 a=”x”b=”y”)会失效;生产环境建议用更严谨的 tokenizer 或正则全局匹配 /w+s*=s*(“[^”]*”|'[^’]*’|[^s]+)/g;
  • 回调函数中 match 参数包含完整匹配项,attrsBlock(即捕获组1)是去除了 @#@ 边界的原始属性块,务必 .trim() 清除首尾空白再处理;
  • 若属性值含转义引号(如 “a\”b”),需增强解析逻辑,此处为教学简化,实际项目推荐使用专用解析器(如 parse-attributes 库)。

该方法兼具灵活性与可读性,适用于构建脚本、vs code 插件、或 CI 中的模板标准化流程。掌握 replace 回调模式,是驾驭复杂文本转换的必备技能。

text=ZqhQzanResources