I have regex which uses a look ahead assertion to match strings of the format {{ x }}. The regex is /(?<=\{\{\s)[^}\s]+(?=\s*\}\})/gm
How can I achieve this without using a look ahead assertion?
I have regex which uses a look ahead assertion to match strings of the format {{ x }}. The regex is /(?<=\{\{\s)[^}\s]+(?=\s*\}\})/gm
How can I achieve this without using a look ahead assertion?
A regex like /\{\{\s*([^}]+?)\s*\}\}/g
which does match more loose variants of the OP's {{ x }}
-pattern by making use of ...
capturing groups for targeting every character which is not a closing curly brace except of (optional) leading and trailing whitespace (sequences) ... and a ...
lazy (non greedy) quantifier for the pattern's termination of an optional whitespace (sequence) followed by two closing curly braces ... applied via ...
... does the trick.
const sampleDate =
`{{1}} {{}} {{ 24 56 48 }}
{{ 245648}}{{ 123 }}`;
console.log(
// see ... [https://regex101.com/r/uPFdrO/1]
[...sampleDate.matchAll(/\{\{\s*([^}]+?)\s*\}\}/g)]
.map(([match, capture]) => capture)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
And altering the capturing pattern from [^}]
to [^}\s]
does enforce captures which do not contain any space characters. The lazy quantifier then can be dropped as well ...
const sampleDate =
`{{1}} {{}} {{ 24 56 48 }}
{{ 245648}}{{ 123 }}`;
console.log(
// see ... [https://regex101.com/r/uPFdrO/2]
[...sampleDate.matchAll(/\{\{\s*([^}\s]+)\s*\}\}/g)]
.map(([match, capture]) => capture)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Adding to the other answers, if you want a list of all "x values", you can produce one by repeatedly evaluating m[1]
, which is the first group, where m
is one of the matches.
The following variants with and without lookaround are equivalent:
/* With lookaround */
const s = "{{ 1 }}{{ 2 }}";
console.log(s.match(/(?<=\{\{\s*)[^}\s]+(?=\s*\}\})/gm));
/* Without lookaround */
for (var matches = [], m, regex = /\{\{\s*([^}\s]+)\s*\}\}/gm; m = regex.exec(s);)
matches.push(m[1]);
console.log(matches);
The question remains, however: Why do you want to avoid lookarounds?
Try with this:
\{\{\s([^}\s]+)\s*\}\}
Your result will be inside the first group (the rules inside ()
)
const regex = /{{\s([^}\s]+)\s}}/gm;
const input = "text {{ x }} and {{ y }}.";
const matches = input.match(regex);
if (matches) {
const capturedContent = matches.map(match => match.replace(regex, '$1'));
console.log(capturedContent);
}