繁体   English   中英

如何使用 JavaScript 解析带有双花括号的字符串?

[英]How can I parse a string with double curly brackets, using JavaScript?

是否有一种快速的正则表达式方法或类似方法可以获取字符串并将其解析为不在双花括号中的位(让我们称之为“静态”)和在双大括号中的位(让我们称之为“动态”)?

例如,输入:

Lorem {{ipsum dolor sit}} amet, {consectetur} adipiscing {{elit}}.

所需输出:

[
  {
    type: "static",
    value: "Lorem "
  },
  {
    type: "dynamic",
    value: "ipsum dolor sit"
  },
  {
    type: "static",
    value: " amet, {consectetur} adipiscing "
  },
  {
    type: "dynamic",
    value: "elit"
  },
  {
    type: "static",
    value: "."
  },
]

到目前为止,我最好的尝试是使用/\{*([^{}]+)\}*/g作为正则表达式并循环使用whileexec但它错误地将任意数量的大括号识别为动态值,如此处显示:

 function templateParser(string) { const re = /\{*([^{}]+)\}*/g; const output = []; while (true) { const match = re.exec(string); if (!match) { break; } const [templateItem, templateKey] = match; output.push({ type: templateItem === templateKey ? "static" : "dynamic", value: templateItem === templateKey ? templateItem : templateKey }); } return output; } console.log( templateParser( "Lorem {{ipsum dolor sit}} amet, {consectetur} adipiscing {{elit}}." ) );

现在我对您正在尝试做的事情有了更多的了解,这可能会有所帮助:

let mystring = 'test {{hello}} goodbye {{foo}} bar {foobar}';
let regex = /{{(.*?)}}/g;

console.log( mystring.match( regex ) );

输出

["{{hello}}", "{{foo}}"]

它对每个带有双括号的字符串进行惰性匹配,将匹配项放入一个数组中。 然后,您可以将这些子字符串替换为包含 jsx 标记或类似内容的修改版本。

https://jsfiddle.net/u7gkz341/

编辑:

 let mystring = 'test {{hello}} goodbye {{foo}} bar {foobar}'; let regex = /{{(.*?)}}/g; let match; let lastMatchIndex = 0; let results = []; while ( ( match = regex.exec( mystring ) ) !== null ) { results.push( mystring.substring( lastMatchIndex, match.index ) ); // adds static content up until match results.push( match[1] ); // adds dynamic matched content lastMatchIndex = regex.lastIndex; } results.push( mystring.substring( lastMatchIndex ) ); // adds static remainder of string console.log( results );

编辑:另一个答案应该归功于使用积极的前瞻。 使用该正则表达式,完整的解决方案将是:

Array.from(s.matchAll(/{{(.*?)}}|.+?(?={{|$)/g))
  .map(e=>({type: e[1] ? 'dynamic' : 'static', value: e[1] ?? e[0]}))

或使用命名的捕获组:

Array.from(s.matchAll(/{{(?<dynamic>.*?)}}|(?<static>.+?)(?={{|$)/g))
  .flatMap(e=>Object.entries(e.groups))
  .filter(e=>e[1]).map(e=>({type: e[0], value: e[1]}))

上一个答案:

let s = `Lorem {{ipsum dolor sit}} amet, {consectetur} adipiscing {{elit}}.`;
let result = [{a: 0, b: 0}, ...Array.from(s.matchAll(/{{.*?}}/g))
  .map(e=>({a: e.index, b: e.index+e[0].length}))]
  .map((e, i, arr) => [
    {type: 'dynamic', a: e.a, b: e.b},
    {type: 'static', a: e.b, b: i===arr.length-1 ? s.length : arr[i+1].a}
  ])
  .flat().map(o=>({type: o.type, value: s.substring(o.a, o.b)}))
  .filter(e=>e.value.length>0)
  .map(o=>o.type==='static' ? o :
    {type: 'dynamic', value: o.value.substring(2, o.value.length-2)});

这样做是找到包含在双括号中的所有字符串,然后将它们映射到具有开始和结束索引ab的对象数组。

这些将是动态范围。 然后我们填充数组中的空白以获得静态范围。

最后,我们清除空范围并从动态字符串中修剪双括号。

{{ this }}that区分开来捕获this匹配that的想法。

{{(.*?)}}|.+?(?={{|$)

请参阅 regex101 上的这个演示或 tio.run上的JS 演示

使用exec可以根据m[1]!=null轻松设置您的值(第一组匹配)。 当然,这是根据您的示例数据。 假设没有嵌套,也没有猜测其他任何东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM