Home > Back-end >  How to transform template interpolation with another words to valid expression syntax in js regex?
How to transform template interpolation with another words to valid expression syntax in js regex?

Time:12-25

I have a string containing template interpolation and words not inside template interpolation. The string can have only those various forms:

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

The text interpolation can appear more than once in the string also the words that are not inside the template interpolation can be more than one.

I want to transform the string by this way: remove the double curly brackets and keep the content. another words are not inside double curly brackets need to wrap with single quote and concat between them using .

The finial results should generate the string to another string like that:

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'

So I create a regex str.replace(/{{(.*?)}}/g, '$1').replace(/\b(\w )\b/g, "'$1'")

The first regex is to remove the double curly brackets. The second regex is to wrap word(s) with a single quote.

But I got every result wrapped with a single quote. also no contact between them (not sure where to use in which regex)

How can I change the regex so it will fit my requirements?

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

CodePudding user response:

Instead of replacing, consider matching either bracketed segments or non-bracketed segments. Then you can map each bracketed segment to a substring without brackets, and each non-bracketed segment to its version with single quotes. Finally, join by 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));

{{[^}] }}|[^{] - match either

  • {{[^}] }} - Non-} characters inside {{ }}, or
  • [^{] - One or more non-{characters
  • Related