Elie G.
Elie G.

Reputation: 1723

Groovy Regular Expressions With Group

I'm looking for a regular expression in groovy which would match all these and which would have a group matching the specified part in these examples:

  1. priority = "4-Not Prioritized Yet" ⇒ Group: 4-Not Prioritized Yet
  2. priority != "4-Not Prioritized Yet" ⇒ Group: 4-Not Prioritized Yet
  3. priority = High ⇒ Group: High
  4. priority = "2-Medium" ⇒ Group: 2-Medium
  5. priority changed ⇒ No Group
  6. priority is EMPTY ⇒ No Group


I've tried several regex pattern like:

but I can't find a pattern that works with all the examples. So I would like to know what is wrong with my regex and what pattern would work on all the examples.

What I'm trying to do exactly is something like this:

def str = "{project = "TEST"} AND {priority = "4-Not Prioritized Yet"} OR {priority is EMPTY} OR {priority changed} OR {priority = "2-Medium"} OR {priority = "1-High"} OR {priority = "test"} order by priority DESC"
str.replaceAll(/(?i)\{([^\}]+)\}/) {a, b-> 
    if(b.startsWith("priority")) {
        def regex = /(?i)priority([^\w]+)([^"]+)/
        def match = (b =~ regex);
        /* And now I would like to do something like:
           if (match has group) 
               return b.replace(group, "something else")
           else return b */
    } else return b;
}

Upvotes: 0

Views: 3547

Answers (1)

Valdi_Bo
Valdi_Bo

Reputation: 30971

You can use the following regex:

priority (?:(changed|is EMPTY)|!?= ("?)([^"}]+)\2)

Description:

  • priority - match literal chars (common begin).
  • (?: - Start of a non-matching group. It is necessary because it contains variants.
  • (changed|is EMPTY) - Variant 1 (first capturing group) - catches both cases to be replaced with No Group.
  • | - Variants separator.
  • !?= - Start of variant 2 - match literal chars (optional ! and =).
  • ("?) - Capturing group 2 - catch quote (if any).
  • ([^"}]+) - Capturing group 3 - the priority value string.
  • \2- Match what was captured by group 2.
  • ) - End of the non-capturing group.

And below you have an example program, printing both original and replaced string:

def str = '{project = "TEST"} AND {priority = "4-Not Prioritized Yet"}\
 OR {priority is EMPTY} OR {priority changed} OR {priority = "2-Medium"}\
 OR {priority = "1-High"} OR {priority = "test"} order by priority DESC'
println str
def res = str.replaceAll(/priority (?:(changed|is EMPTY)|!?= ("?)([^"}]+)\2)/) {
  m, g1, g2, g3 ->
  if (g1?.trim()) {
    return "No Group"
  } else if (g3?.trim()) {
    return "Group: $g3"
  } else {
    return m
  }
}
println res

The closure - argument of replaceAll has arguments:

  • m - the whole match,
  • g1 ... g3 - the content captured by respective capturing groups.

If group 1 catched sometning, we have either of No Group cases.

Group 2 catches a quote (if any).

If group 3 catched sometning, we have Group ... case.

And one remark about your program: replaceAll does not edit the text "in place". The replaced text is returned as the result of this function and the original string is not changed. So it is necessary to save the result of this function.

Upvotes: 2

Related Questions