javascript 如何在js正则表达式中将带有其他单词的模板插值转换为有效的表达式语法?

but5z9lq  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(113)

我有一个字符串包含了模板插值和不在模板插值内的单词。这个字符串只能有以下几种形式:

foo{{bar}}
{{foo}}bar
foo{{bar}}baz
{{foo}}{{bar}}
foo
{{foo}}
{{foo}}bar{{baz}}

文本插值可以在字符串中出现多次,不在模板插值内的单词也可以不止一个。
我想用这样的方法转换字符串:删除双花括号并保留内容。另一个单词不在双花括号内,需要用单引号和concat在它们之间使用+
最终结果应该会将字符串生成为另一个字符串,如下所示:

foo{{bar}}       // <-- 'foo' + bar
{{foo}}bar       // <-- foo + 'bar'
foo{{bar}}baz    // <-- 'foo' + bar + 'baz'
{{foo}}{{bar}}   // <-- foo + bar
foo              // <-- 'foo'
{{foo}}          // <-- foo
{{foo}}bar{{baz}} //<-- foo + 'bar' + 'baz'

我创建了一个正则表达式str.replace(/{{(.*?)}}/g, '$1').replace(/\b(\w+)\b/g, "'$1'")
第一个正则表达式是删除双花括号。第二个正则表达式是用单引号括住单词。
但是我得到的每个结果都用一个单引号 Package 。它们之间也没有联系(不确定在哪个正则表达式中使用+
我怎样才能改变正则表达式,使它符合我的要求?

const strs = [
  'foo{{bar}}',
  '{{foo}}bar',
  'foo{{bar}}baz',
  '{{foo}}{{bar}}',
  'foo',
  '{{foo}}',
  '{{foo}}bar{{baz}}'
];

let result = strs.map((s) =>
  s.replace(/{{(.*?)}}/g, '$1').replace(/\b(\w+)\b/g, "'$1'")
);

result.forEach((r) => console.log(r));

stackblitz

zkure5ic

zkure5ic1#

不要替换,考虑 matching 带括号的段或不带括号的段,然后可以将每个带括号的段Map到不带括号的子字符串,将每个不带括号的段Map到带单引号的版本,最后,通过+ s进行连接。

const strs = [
  'foo{{bar}}',
  '{{foo}}bar',
  'foo{{bar}}baz',
  '{{foo}}{{bar}}',
  'foo',
  '{{foo}}',
  '{{foo}}bar{{baz}}',
];

let result = strs.map((s) =>
  s
    .match(/{{[^}]+}}|[^{]+/g)
    .map(substring =>
      substring.startsWith('{')
        ? substring.slice(2, substring.length - 2)
        : "'" + substring + "'"
    )
    .join(' + ')
);

result.forEach((r) => console.log(r));

{{[^}]+}}|[^{]+-匹配任一项

  • {{[^}]+}}-{{}}中的非}字符,或
  • [^{]+-一个或多个非{字符

相关问题