1

I have a string containing placeholders which I want replace with other strings, but I would also like to split the string whenever I encounter a placeholder.

So, by splitting I mean that

"This {0} is an example {1} with a placeholder"

should become:

parts[0] -> "This"
parts[1] -> "{0}"
parts[2] -> "is an example"
parts[3] -> "{1}"
parts[4] -> "with a placeholder"

and then the next step would be to replace the placeholders (this part is simple):

parts[0] -> "This"
parts[1] -> value[0]
parts[2] -> "is an example"
parts[3] -> value[1]
parts[4] -> "with a placeholder"

I know how to match and replace the placeholders (e.g. ({\d+})), but no clue how to tell regex to "match non placeholders" and "match placeholders" at the same time.

My idea was something like: (?!{\d+})+ | ({\d+}) but it's not working. I am doing this in JavaScript if Regex flavor is important.

If I can also replace the placeholders with a value in one step it would be neat, but I can also do this after I split.

Lou
  • 4,244
  • 3
  • 33
  • 72

2 Answers2

2

You might write the pattern as:

{\d+}|\S.*?(?=\s*(?:{\d+}|$))

The pattern matches:

  • {\d+} Match { 1+ digits and }
  • | Or
  • \S.*? Match a non whitespace char followed by any character as few as possible
  • (?= Positive lookahead
    • \s* Match optional whitespace chars
    • (?:{\d+}|$) Match either { 1+ digits and } or assert the end of the string
  • ) Close the lookahead

Regex demo

To get an array with those values:

const regex = /{\d+}|\S.*?(?=\s*(?:{\d+}|$))/gm;
const str = `This {0} is an example {1} with a placeholder`;
console.log(str.match(regex))
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

If you use parenthesis around the separator, matched results are included in the output:

let parts = str.split(/ *({\d+}) */);

See this demo at tio.run - If separator occurs at start/end, just filter out empty matches.


If your goal is just to replace, it can be done in one step using replace and a callback:

str = str.replace(/{(\d+)}/g, (m0, m1) => value[m1]);

Another demo at tio.run - m0 is the full match, m1 holds the capture of the first group.
Used with g (global) flag to return all possible matches in the string (not just the first).

bobble bubble
  • 16,888
  • 3
  • 27
  • 46