Raffaeu
Raffaeu

Reputation: 6983

Regex split iif expression

I am trying to test a Regex which should be able to split the following expressions into 3 parts:

If there are multiple iif nested, it should give me multiple matches

And I have some patterns:

iif(testExpression, trueExpression, falseExpression)

iif((@HasMinimunRegulatedCAR@==0),(([t219]>1.5) OR ([t219]<-0.5)),(([t223]>1.5) OR ([t223]<-0.5)))

iif((@HasMinimunRegulatedCAR@==1), iif((@MFIUsePAR30@==1), ([t224]>0.25), iif((@MFIUsePAR90@==1), ([t225]>0.25), (1==1))), iif((@MFIUsePAR30@==1), ([t220]>0.25), iif((@MFIUsePAR90@==1), ([t221]>0.25),(1==1))))

I am using this expression but it doesn't work when I have multiple iif nested

(^(iif\()|[^,]+)

I am running my tests using: https://regex101.com/

The expected output should be

testExpression
trueExpression
falseExpression

(@HasMinimunRegulatedCAR@==0)
([t219]>1.5) OR ([t219]<-0.5)
([t223]>1.5) OR ([t223]<-0.5)

(@HasMinimunRegulatedCAR@==1)
iif((@MFIUsePAR30@==1), ([t224]>0.25), iif((@MFIUsePAR90@==1), ([t225]>0.25), (1==1)))
iif((@MFIUsePAR30@==1), ([t220]>0.25), iif((@MFIUsePAR90@==1), ([t221]>0.25),(1==1)))

Upvotes: 1

Views: 348

Answers (1)

Kobi
Kobi

Reputation: 138117

If .Net regular expressions are an option, you can use balancing groups to capture your iifs.

One option will capture all nested parentheses into a group called Exp:

(?>
    (?:iif)?(?<Open>\((?<Start>))   # When seeing an open parenthesis, mark
                                    # a beginning of an expression. 
                                    # Use the stack Open to count our depth.
    |
    (?<-Open>(?<Exp-Start>)\))      # Close parenthesis. Capture an expression.
    |
    [^()\n,]                        # Match any regular character
    |
    (?<Exp-Start>),(?<Start>)       # On a comma, capture an expression, 
                                    # and start a new one.
)+?
(?(Open)(?!))

Working Example, switch to the Table tab.
This option captures more than you ask for, but it does give you the full data you need to fully parse the equation.

Another option is to capture only the top-level parts:

iif\(
(?:
  (?<TopLevel>(?>
      (?<Open>\()     # Increase depth count using the Open stack.
      |
      (?<-Open>\))    # Decrease depth count.
      |
      [^()\n,]+       # Match any other boring character
      |
      (?(Open),|(?!)) # Match a comma, bun only if we're already inside parentheses.  
  )+)
  (?(Open)(?!))
  |
  ,\s*   # Match a comma between top-level expressions.
)+
\)

Working Example Here, the group $TopLevel will have three captures. For example, on your last example, it captures:

Capture 0: (@HasMinimunRegulatedCAR@==1)
Capture 1: iif((@MFIUsePAR30@==1), ([t224]>0.25), iif((@MFIUsePAR90@==1), ([t225]>0.25), (1==1)))
Capture 2: iif((@MFIUsePAR30@==1), ([t220]>0.25), iif((@MFIUsePAR90@==1), ([t221]>0.25),(1==1)))

Upvotes: 1

Related Questions