Brandon Frohbieter
Brandon Frohbieter

Reputation: 18139

Regular expression to match all but an ending condition

I am trying to match {{anything}} using the regular expression

 /\{\{.*\}\}/

But it will not end upon the first }}, but on the last in the document.

{{anything}} {{anotherthing}}

will return that whole chunk, instead of two matches. How can I formulate this expression to be less greedy?

I tried to do

 /\{\{[^\}].*\}\}/

but it returned no results, same thing for

/\{\{.*?\}\}/

Bonus - to not get the curlies, but just the string, I tried

 /\{\{(.*)\}\}/

with more failure (returned empty as well). How can I also get a subset of a match?

One time my teacher told me that she could teach me regular expressions in 15 minutes. I never got that lesson, and I'm not convinced. :)

Upvotes: 2

Views: 170

Answers (3)

tripleee
tripleee

Reputation: 189607

If your flavor of regex does not support non-greedy *? (they are a novelty introduced in Perl, and not available in "classical" regex such as grep, sed, etc) you have to do something like

\{\{([^}]+|}[^}])*)\}\}

again with the caution that different regex flavors demand different backslash escapes (the sed in Linux, for example, would omit the backslash before the curly brackets, but requires backslash before the parentheses and alternation operator, thus {{\([^}]\+\|}[^}])*}} -- also note the backslash before the plus repetition operator).

So just to spell that out; literal {{ followed by either a sequence of characters which are not closing curly bracket [^}] or by a literal curly bracket but something else than another literal curly bracket }[^}] and finally the closing literal double curly brackets }}.

Upvotes: 2

MaxiWheat
MaxiWheat

Reputation: 6261

You should use a non-greedy star to achieve this (adding the question mark) :

 /\{\{.*?\}\}/

You can read more on this here

For the last part, matching only the string without the braces, take a look at "lookbehind" and "lookahead" here

Upvotes: 2

Alex Howansky
Alex Howansky

Reputation: 53581

Use the "not" operator in the middle:

/\{\{[^\{\}]*\}\}/

I.e., inside the {{ and }} you can have anything BUT a { or }.

And if you want to capture the inside:

/\{\{([^\{\}]*)\}\}/

Upvotes: 1

Related Questions