You need to enable JavaScript to run this app. 如何按正则匹配拆分含占位符的字符串为数组并处理嵌套数组,有无模板库
优惠活动
大模型
产品
解决方案
定价
更多

如何按正则匹配拆分含占位符的字符串为数组并处理嵌套数组,有无模板库

实现思路

核心是放弃字符串拼接替换逻辑,改为按正则匹配位置拆分原字符串,再将匹配项映射为目标值插入拆分后的片段,同时配合递归处理嵌套数组。

具体实现

1. 单个字符串拆分工具函数

先实现处理单个字符串的逻辑,按匹配项位置切分,自动过滤空文本段:

/**
 * 按指定正则拆分字符串,匹配项映射为自定义值
 * @param {string} str 待处理原字符串
 * @param {RegExp} matchReg 全局匹配规则(需带g修饰符)
 * @param {(matchStr: string, matchInner: string) => any} mapMatchFn 匹配项映射函数,返回对应数组元素
 * @returns {any[]} 拆分后的数组
 */
function splitStrByMatch(str, matchReg, mapMatchFn) {
  const segments = [];
  let lastCursor = 0;
  // 遍历所有匹配项
  for (const match of str.matchAll(matchReg)) {
    const matchStart = match.index;
    const matchEnd = matchStart + match[0].length;
    // 提取当前匹配前的非匹配文本,过滤空值
    const beforeText = str.slice(lastCursor, matchStart).trim();
    if (beforeText) segments.push(beforeText);
    // 插入匹配项的映射结果
    segments.push(mapMatchFn(match[0], match[1]));
    // 更新游标到匹配项末尾
    lastCursor = matchEnd;
  }
  // 处理最后一个匹配后的剩余文本
  const afterText = str.slice(lastCursor).trim();
  if (afterText) segments.push(afterText);
  return segments;
}

效果验证

用给出的示例测试:

const testStr = 'stufff sjktasjtjser ((matchthis))';
// 匹配双括号规则,匹配项统一映射为'whatwhat'
const result = splitStrByMatch(testStr, /\(\((.*?)\)\)/g, () => 'whatwhat');
console.log(result); // 输出 ['stufff sjktasjtjser', 'whatwhat'],符合预期

若字符串无匹配项,会直接返回包含原字符串的单元素数组;若字符串为纯匹配内容,会直接返回映射后的目标值数组,不会出现空数组。

2. 嵌套数组递归处理

通过递归遍历嵌套数组的每一项,字符串类型元素执行上述拆分逻辑,数组类型元素递归处理,其他类型(如原有对象)直接保留:

/**
 * 递归处理嵌套数组的字符串元素
 * @param {any[]} arr 待处理嵌套数组
 * @param {RegExp} matchReg 全局匹配规则
 * @param {Function} mapMatchFn 匹配项映射函数
 * @param {boolean} flatten 是否将拆分后的数组展开到上层(默认false)
 * @returns {any[]} 处理后的新数组
 */
function processNestedArr(arr, matchReg, mapMatchFn, flatten = false) {
  const handler = flatten ? Array.prototype.flatMap : Array.prototype.map;
  return handler.call(arr, item => {
    if (Array.isArray(item)) {
      return processNestedArr(item, matchReg, mapMatchFn, flatten);
    }
    if (typeof item === 'string' && item) {
      return splitStrByMatch(item, matchReg, mapMatchFn);
    }
    return item;
  });
}

嵌套数组效果验证

const nestedTestArr = ['stufff', ['more stuff ((matchhere))'], '((andanother))'];
// 默认不展开,保留原数组层级
const processedDefault = processNestedArr(nestedTestArr, /\(\((.*?)\)\)/g, () => 'whatwhat');
/* 输出:
[
  ['stufff'],
  [['more stuff', 'whatwhat']],
  ['whatwhat']
]
*/
// 开启展开,拆分后的数组直接合并到上层
const processedFlatten = processNestedArr(nestedTestArr, /\(\((.*?)\)\)/g, () => 'whatwhat', true);
/* 输出:
['stufff', 'more stuff', 'whatwhat', 'whatwhat']
*/
灵活适配自定义输出需求

如果需要输出对象数组而非纯字符串,只需修改传入的mapMatchFn即可:

// 示例:将匹配项映射为指定结构的对象
const mapToObj = (matchStr, matchInnerContent) => ({
  type: 'replaceNode',
  originText: matchInnerContent,
  target: 'whatwhat'
});
const processedWithObj = processNestedArr(nestedTestArr, /\(\((.*?)\)\)/g, mapToObj);
// 输出的数组中匹配项将直接为对应对象结构,无需额外转换
关于第三方库

不需要专门的模板库,上述逻辑完全可以自主实现。如果希望简化递归遍历的代码,可以使用通用工具库(如Lodash)提供的递归节点遍历方法,核心逻辑和上述实现一致,灵活性更高。

内容的提问来源于stack exchange,提问作者Ricardo Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 16:57:03