Got more questions? Find advice on: ASP | SQL | XML | Windows
in Search
Welcome to RegexAdvice Sign in | Join | Help

Matching a preceeding matching sqare bracket

Last post 03-03-2010, 8:57 PM by Peadarin. 2 replies.
Sort Posts: Previous Next
  •  01-19-2010, 7:59 AM 58598

    Matching a preceeding matching sqare bracket

    Hi All,

    I'm trying to make modifications to industrial control ladder logic and have been quite successful so far. I'm now stumped at trying to create a regex to remove some code.

    A bit of background so you understand what I'm trying to do. The code is essentially a big if-then statement.

    For example,

    N: [XIC(bit_a), XIC(bit_b)  XIC (bit_c)] OTE (bit_e);

    Means

    new rung, IF (bit_a == 1 OR (bit_b == 1 AND Bit_c == 1)) then bit_e = 1 end of rung

    What  I'm trying to do is take out the second OR condition.  The pseudo-regex  is

    "Opening [" (intervening code into capture group 1) ", OR condition closing ]" (remaining code ; into capture group 2)

    and replace with 

    Capturegroup1 Capturegroup2

    This works fine as long as  (intervening code into capture group 1) doesn't contain any parallel branches. If it does, I'm capturing the entire code from the (incorrect)opening bracket to the correct closing one. What I need to do is find my OR condition and attached closing bracket and capture up to the matching opening bracket.

    Example Working Test Data
    Original data:

            N: [XIO(F7_72_0752.HMI.Status.Auto) ,XIC(AlarmSeverity4.Active[6].18) XIO(AlarmSeverity4.Ack[6].18) ]OTE(AlarmSeverity4.Active[6].18);

    Using regex  replace

    \[(.*?),XIC\(AlarmSeverity[\d]\.Active\[[\d]{1,2}\]\.[\d]{1,2}\) XIO\(AlarmSeverity[\d]\.Ack\[[\d]{1,2}\]\.[\d]{1,2}\) ]

    With

    \01

    Results in

    N: XIO(F7_72_0752.HMI.Status.Auto) OTE(AlarmSeverity4.Active[6].18);

    which is correct.

    Using orignial the original data With an extra OR condition (and so extra opening square bracket)

    N: [XIC(F7_72_0714.GY.A) XIO(F7_72_0714.GS.H) TON(F7_72_0714.HMITimers[0].Timer,?,?) ,[XIC(F7_72_0714.HMITimers[0].Timer.DN) ,XIC(AlarmSeverity4.Active[8].21) XIO(AlarmSeverity4.Ack[8].21) ]  OTE(AlarmSeverity4.Active[8].21) ];

    With the same regex search and replace results in 

    N: XIC(F7_72_0714.GY.A) XIO(F7_72_0714.GS.H) TON(F7_72_0714.HMITimers[0].Timer,?,?) ,[XIC(F7_72_0714.HMITimers[0].Timer.DN) OTE(AlarmSeverity4.Active[8].21) ];

    Whereas it should be

    N: [XIC(F7_72_0714.GY.A) XIO(F7_72_0714.GS.H) TON(F7_72_0714.HMITimers[0].Timer,?,?) ,XIC(F7_72_0714.HMITimers[0].Timer.DN) OTE(AlarmSeverity4.Active[8].21) ];

    See how it's taken the opening square bracket at the beginning of the line, instead of the balancing one before  ",[XIC(F7_72_0714"?

     the Regex

    ,XIC\(AlarmSeverity[\d]\.Active\[[\d]{1,2}\]\.[\d]{1,2}\) XIO\(AlarmSeverity[\d]\.Ack\[[\d]{1,2}\]\.[\d]{1,2}\) ]

    accurately selects the condition I'm after, but I need to capture the matching opening square bracket for the one I've just captured above.

     I'm using powerGREP and RegexBuddy.

    Many thanks,

    Kevin Jones

     

  •  03-02-2010, 5:44 PM 60295 in reply to 58598

    Re: Matching a preceeding matching sqare bracket

     

    \[(.*) is extremely greedy inside your rule and eats everything everithing everything on the left until the leftmost bracket. The lazy quantifier *? you put will not work exactly as you wish. This is why you match the wrong [

    since you do not want to cross [ and only replace inner [ ] , you must exclude the opening square brackets from the "big slurper"   .* 

    So replace . (dot) by  ^[ (not a open sq. bracket) in a character class [ ]  , and you rule becomes

    \[[^[]*,XIC\(AlarmSeverity ..........

     I love pcre, that's unreadable :-)   or a smiley. \[[^[]* for a policeman in a toothpaste ad.

    I suggest to use \x5b to clarify what is byte and what is part of the rule structure

    \x5b[^\x5b]*.XIC\(AlarmSeverity ..........

     This should match the [ you expect, and not the leftmost one.

    Does it solve your matching problem ? Note that regex is terribly useless for matching balanced elements unless you are in the innermost part of it. When you get to 2 levels of [ ] then .. that would be terrible (or processing in 2 passes)

     

  •  03-03-2010, 8:57 PM 60324 in reply to 60295

    Re: Matching a preceeding matching sqare bracket

    My response was too quick

    Try this

    ,\x5b[^,]*?,XIC\(AlarmSeverity[\d]\.Active\[[\d]{1,2}\]\.[\d]{1,2}\) XIO\(AlarmSeverity[\d]\.Ack\[[\d]{1,2}\]\.[\d]{1,2}\) ]

    ,\x5bXIC[^,]*?,XIC\(AlarmSeverity[\d]\.Active\[[\d]{1,2}\]\.[\d]{1,2}\) XIO\(AlarmSeverity[\d]\.Ack\[[\d]{1,2}\]\.[\d]{1,2}\) ]

    but the problem of matching balancing [ ] where there are \[[\d]\] within, using lazy operator is quasi impossible

    I guess there are more general possibilities with lookahead operators, but you have only one example, it is hard to generalize.

    Just let suppose that you have 3 letters after the [ you want to match , the following expression works too, and select what you wish in your example

    ,\[(?=[A-Z]{3}).*? XIO\(AlarmSeverity[\d]\.Ack\[[\d]{1,2}\]\.[\d]{1,2}\) \]

     

     

View as RSS news feed in XML