'Match Operator prettier syntax in Groovy

I'm very new to groovy (here working on Jenkinsfile)

One of my coworkers uses a Match Operator to check a condition. But I find it not readable and hard to maintain.

Original Match Operator:

PROJECT_NAME = 'projectA' // User Input from Jenkins params normaly
if ( "${PROJECT_NAME}" ==~ /projectA|projectB|projectC|projectD/) { // The real line is 300 Char long
    // Do stuff
}

There is 15 projects in total, i've shorten up the line because it was too long. So every time he needs to add a project name, he appends at the start or end of his regex.

Also, those project name are in a list before.

projects = ['projectA',
    'projectB',
    'projectC',
    'projectD']

Could there be a way to use this list to build the regex?

Here is what I tried:

string_regex = "/"
for (project in projects) {
    string_regex = string_regex + project + "|" 
}
string_regex = string_regex.substring(0, string_regex.length() - 1)
string_regex = string_regex + "/"

print "${string_regex}\n"

if ("${PROJECT_NAME}" ==~ string_regex) {
    print "Well Done you did it\n"
    // Do stuff
}

But saddly it doesn't seems to work, since I'm using a string?

EDIT: I found out that I could use the contains method from a list in Groovy. In my case, it fixes my original problem. But I'm still curious on how to build such regex with strings.

if (projects.contains(PROJECT_NAME)) {
    // Do stuff
}


Solution 1:[1]

You can join your projects and then turn the string into a regexp via Pattern.compile(). For good measure use Pattern.quote() to safe-guard against chars in your project names with "meaning" in regexp.

import java.util.regex.Pattern

def projects = ['projectA',
    'projectB',
    'projectC',
    'projectD']

def re = Pattern.compile(projects.collect{ Pattern.quote it }.join("|"))

['projectA', 'projectX'].each{
    println it ==~ re
}
// -> true
// -> false

Solution 2:[2]

For what it's worth, I came to like the Groovy matching operators for their compact syntax. If you learn about them and practice for a short bit, you will probably get to like them, too.

Regardless, for a simple check, on whether a String is part of a list, there is a much simpler way in Groovy than using full blown regexp : the in operator, e.g.:

def projects = ['projectA',
    'projectB',
    'projectC',
    'projectD']

['projectA', 'projectX'].each {
    println "${it} is ${it in projects ? 'IN' : 'NOT IN'} the project list"
}

which yields e.g.:

projectA is IN the project list
projectX is NOT IN the project list

More info on that operator and many other aspects of the Groovy language from the always excellent MrHaki here

Of course, if you need to account for case differences, etc... you have to massage the code a bit, but at some point, a regexp might be warranted.

Solution 3:[3]

If you have already an collection, you should nearly always use an collection operator; E.g. replace

if ( "${PROJECT_NAME}" ==~ /projectA|projectB|projectC|projectD/) {

with:

if (PROJECT_NAME in projects) {

Much easier to read and understand, no? ?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cfrick
Solution 2 Patrice M.
Solution 3 Jost Schwider