regexkeyboard-maestro

How to do a complex multiple if-then-else regex?


I need to do a complex if-then-else with five preferential options. Suppose I first want to match abc but if it's not matched then match a.c, then if it's not matched def, then %#@, then 1z;.

Can I nest the if-thens or how else would it be accomplished? I've never used if-thens before.

For instance, in the string 1z;%#@defarcabcaqcdef%#@1z; I would like the output abc.

In the string 1z;%#@defarcabaqcdef%#@1z; I would like the output arc.

In the string 1z;%#@defacabacdef%#@1z; I would like the output def.

In the string 1z;#@deacabacdf%#@1z; I would like the output %#@.

In the string foo;%@dfaabaef#@1z;barbbbaarr3 I would like the output 1z;.


Solution

  • You need to force individual matching of each option and not put them together. Doing so as such: .*?(?:x|y|z) will match the first occurrence where any of the options are matched. Using that regex against a string, i.e. abczx will return z because that's the first match it found. To force prioritization you need to combine the logic of .*? and each option such that you get a regex resembling .*?x|.*?y|.*?z. It will try each option one by one until a match is found. So if x doesn't exist, it'll continue to the next option, etc.

    See regex in use here

    (?m)^(?:.*?(?=abc)|.*?(?=a.c)|.*?(?=def)|.*?(?=%#@)|.*?(?=1z;))(.{3})
    

    If the options vary in length, you'll have to capture in different groups as seen here:

    (?m)^(?:.*?(abc)|.*?(a.c)|.*?(def)|.*?(%#@)|.*?(1z;))