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.
CodePudding user response:
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
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))
CodePudding user response:
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).