5

In implementing a small script parser I've come across a problem with this sample of code - in wanting to select only the part between and including the "if { }" statements, it's being greedy and selecting all including the last line. I guess what I should be using is a negative lookahead.

if [condition1]
{
  task1
  setparameters{a}
  task2
}

if [condition2]
{
  task3
}

setparameters{b}

Currently, I have:

if\b\s\[.*\]\s\{(\s|.)*\}

I guess it's not as simple as breaking on another 'if' either, as something else may come before then. Is it possible to count an equal number of opening and closing braces? Or is there some other magical way that I can just select one of these 'if' statements?

Jamie Barron
  • 101
  • 1
  • 6
  • 1
    You need to learn about `?` and its significance in Regex. A fix: `if\b\s\[.*\]\s\{(\s|.)*?\}` – It'sNotALie. Aug 06 '13 at 13:59
  • Perhaps I should have added a little more qualification as to why I'd not made the * non-greedy - there is the chance that a closing brace } could appear within the loop. I've updated the original to show this. – Jamie Barron Aug 06 '13 at 14:20
  • Ah, then you're starting to look at balancing groups. I didn't know what they were, so I posted a question. The answer is wonderful. Read it: [What are Regular Expression Balancing Groups?](http://stackoverflow.com/questions/17003799/What-are-regular-expression-balancing-groups) – It'sNotALie. Aug 06 '13 at 14:27

2 Answers2

2

I ran into a similar problem when I was trying to detect SQL strings (with the possibility of escaped quotes), try the regex: if.*?\{(\{.*?\}|[^}])*+\}

It will match an if followed by the condition up until the first {, then from then on it will continue matching if it encounters either something between a { and } OR anything that is not a }, followed by the final closing }.

I used the possessive quantifier to prevent the possibility of catastrophic backtracking.

Song Gao
  • 656
  • 4
  • 14
0

Using a "?" as a qualifier makes a "*" non-greedy. In fact, it may be better to use "+":

\[.+?]

As @It'sNotALie said (paraphrased), you would benefit from a bit of explanation:

A sample of a nice tutorial

James Jensen
  • 715
  • 1
  • 7
  • 12