记录将 `{}` 替换成 `{{}}` 的 N 种方法

458 阅读2分钟

背景

有一次业务需要,涉及到将 {} 替换成 {{}}。这里整理一下可行的方法,供大家参考

在使用模板引擎时,我们经常需要将数据以JSON字符串的形式插入到模板中。然而,这些数据中可能包含大括号 {},这可能会与模板引擎的语法产生冲突。为了解决这个问题,我们可以将JSON字符串中的大括号替换为双大括号 {{}}

方法一:使用 split()join()

首先,我们定义一个名为 stringifyWithDoubleBraces 的函数,该函数接受一个对象作为参数,并返回一个将大括号替换为双大括号的JSON字符串。下面是一个简单的实现:

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const stringified = JSON.stringify(data);

  const output = stringified
    .split('{').join('{{')
    .split('}').join('}}');

  return output;
};

这个实现首先使用 JSON.stringify(data) 将传入的对象转换为JSON字符串,然后使用 split()join() 方法替换大括号。例如,如果传入的对象是 {"name": "John", "age": 30},那么 stringifyWithDoubleBraces 函数将返回 {{"name":"John","age":30}}

方法二:使用 replace() 和正则表达式

我们还可以使用 replace() 方法和正则表达式来实现相同的功能:

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const stringified = JSON.stringify(data);

  const output = stringified.replace(/{|}/g, (match) => {
    return match === "{" ? "{{" : "}}";
  });

  return output;
};

这种方法利用正则表达式匹配 {},并通过回调函数将其替换为 {{}}。这种方式更加简洁,并且在处理复杂字符串时表现更好。

方法三:使用 reduce()

我们还可以使用 reduce() 方法将对象转换为一个包含双大括号的字符串:

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const entries = Object.entries(data);
  
  const output = entries.reduce((accumulator, [key, value], index) => {
    const stringifiedValue = JSON.stringify(value);
    const isLastEntry = index === entries.length - 1;
    const entry = `"${key}":${stringifiedValue}${isLastEntry ? '' : ','}`;
    
    return accumulator + entry;
  }, '{{') + '}}';
  
  return output;
};

这种方法通过遍历对象的键值对,并手动构建包含双大括号的字符串。虽然这种方法较为复杂,但它提供了更高的灵活性,可以根据需要进行进一步的定制。

方法四:使用递归函数

我们可以编写一个递归函数来遍历对象的每个属性,并将大括号替换为双大括号。这种方法适用于嵌套对象的情况。

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const replaceBraces = (value: any): any => {
    if (typeof value === 'object' && value !== null) {
      if (Array.isArray(value)) {
        return value.map(replaceBraces);
      } else {
        return Object.keys(value).reduce((acc, key) => {
          acc[key] = replaceBraces(value[key]);
          return acc;
        }, {} as { [key: string]: any });
      }
    }
    return value;
  };

  const replacedData = replaceBraces(data);
  const stringified = JSON.stringify(replacedData);

  return stringified.replace(/{/g, '{{').replace(/}/g, '}}');
};

这种方法通过递归遍历对象的每个属性,确保所有嵌套对象中的大括号都被替换。

方法五:使用 JSON.stringifyreplacer 参数

JSON.stringify 方法的第二个参数 replacer 可以用来定制序列化行为。我们可以利用这个参数来替换大括号。

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const replacer = (key: string, value: any) => {
    if (typeof value === 'string') {
      return value.replace(/{/g, '{{').replace(/}/g, '}}');
    }
    return value;
  };

  const stringified = JSON.stringify(data, replacer);

  return stringified.replace(/{/g, '{{').replace(/}/g, '}}');
};

这种方法利用 replacer 参数在序列化过程中替换字符串中的大括号。

方法六:使用 map 方法处理对象的键值对

我们可以使用 Object.entriesmap 方法来处理对象的键值对,并手动构建包含双大括号的字符串。

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const entries = Object.entries(data).map(([key, value]) => {
    const stringifiedValue = JSON.stringify(value).replace(/{/g, '{{').replace(/}/g, '}}');
    return `"${key}":${stringifiedValue}`;
  });

  return `{{${entries.join(',')}}}`;
};

这种方法通过 map 方法处理对象的每个键值对,并在构建字符串时替换大括号。

方法七:使用 JSON.parseJSON.stringify 结合

我们可以先将对象转换为JSON字符串,然后使用 JSON.parse 将其解析为对象,再次使用 JSON.stringify 进行序列化时替换大括号。

const stringifyWithDoubleBraces = (data: { [key: string]: any }) => {
  const stringified = JSON.stringify(data);
  const parsed = JSON.parse(stringified, (key, value) => {
    if (typeof value === 'string') {
      return value.replace(/{/g, '{{').replace(/}/g, '}}');
    }
    return value;
  });

  return JSON.stringify(parsed).replace(/{/g, '{{').replace(/}/g, '}}');
};

这种方法通过两次序列化和解析来替换大括号,确保所有嵌套对象中的大括号都被替换。

结论

以上几种方法为将JSON字符串中的大括号替换为双大括号提供了多种选择。根据具体需求和场景,可以选择适合的实现方案。无论是使用 split()join() 的简单方法,replace() 和正则表达式的简洁方法,reduce() 的灵活方法,递归函数、JSON.stringifyreplacer 参数,map 方法处理对象的键值对,还是结合 JSON.parseJSON.stringify,完成替换的事情。

大家可以视情况而定,根据业务需要,选择合适的方法