【问题标题】:Processing and replacing text inside double curly braces处理和替换双花括号内的文本
【发布时间】:2019-11-04 14:41:32
【问题描述】:

我有一个 URL 字符串:

var url = https://url.com/{{query}}/foo/{{query2}}

我有一行代码可以接收一个字符串,然后在大括号内得到一个包含所有查询的数组:

var queries = String(url).match(/[^{\}]+(?=})/g);

返回: queries = ['query', 'query2']

我有一个函数parse(queries),它处理这些查询并返回它们的结果列表:

results = ['resultOfQuery', 'resultOfQuery2']

我希望能够获取此列表,然后将 URL 字符串中的查询替换为其结果。这个例子的最终结果是:

url = https://url.com/resultOfQuery/foo/resultOfQuery2

我有两个不同的问题:

  1. String.match 代码行中的正则表达式只计算一组花括号 {something}。如何修改它以查找一组双花括号 {{something}}?

  2. 我已经有了结果数组。进行字符串替换的最佳方法是什么,以便将查询及其随附的每组双括号替换为其相应的结果?

【问题讨论】:

  • 尝试var result = s.replace(/{{(.*?)}}/g, function($0,$1) { return parse($1); } ),但您的parse 函数应该能够接受单个字符串作为参数。
  • {{ ... }}之间的字符串格式有什么限制?例如。它总是一个有效的 JS 变量名吗?
  • {{ }} 之间的字符串可以是任意字符串。我的parse() 函数完成了所有潜在的错误处理。如果用户愿意,它可能是{{foo}}

标签: javascript node.js regex


【解决方案1】:

也适用于嵌套对象的通用解决方案。

function replaceText(text, obj, start = '{{', end = '}}') {
  return text.replace(new RegExp(`${start}(.+?)${end}`, 'g'), (_, part) => {
    return part.split('.')
      .reduce((o, k) => (
        o || {}
      )[k], obj);
  });
}

console.log(replaceText(
  'Hello my name is {{name.first}} {{name.last}}, age: {{age}}',
  {
    name: {
      first: 'first', last: 'last'
    },
    age: 20,
  }
));

要将正则表达式内置符号用作模板,请在每个字符前使用双反斜杠 \\。这是因为上面的函数使用模板字符串new RegExp('\\^(.+?)\\^', 'g')来创建正则表达式而不是RegExp构造函数new RegExp(/\^(.+?)\^/g),否则单个反斜杠就足够了。
例如

(  => \\(
)  => \\)
(( => \\(\\(
)) => \\)\\)
^  => \\^

【讨论】:

    【解决方案2】:

    您可以使用以下模式替换,

    {{(.+?)}}
    
    • {{ - 匹配 {{
    • (.+?) - 一次或多次匹配除换行符以外的任何内容

    let url = "https://url.com/{{query}}/foo/{{query2}}"
    
    let result = {'query': 'queryResult1', 'query2':'queryResult2' }
    
    let replaceDoubleBraces = (str,result) =>{
      return str.replace(/{{(.+?)}}/g, (_,g1) => result[g1] || g1)
    }
    
    console.log(replaceDoubleBraces(url,result))

    注意:- 我在这里使用结果作为对象,因此查找和替换值变得容易,如果您可以更改解析函数,请考虑从解析返回一个对象

    【讨论】:

    • 这里唯一的缺点是如果允许单个} 出现在{{ ... }} 结构中。例如,var url = https://url.com/{{very}weird}indeed}}/foo/
    • @GershomMaes 已更新,IMO 应该限制保持一致
    • 我同意,我认为没有必要在 {{ ... }} 模板中允许使用复杂的术语!
    • 谢谢,我相信这是一个可行的解决方案。即使query 中有括号,我也让用户自己负责找出他们自己的语法错误/错误
    • @CodeManiac 快速跟进另一个问题 - 如果我使用 str.match(/{{(.+?)}}/g),它将返回一个数组 with 双括号,即。 ['{{query}}']。是否有一个只会返回查询本身的正则表达式 ['query']
    猜你喜欢
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多