StoneThrow
StoneThrow

Reputation: 6275

Jenkinsfile/Groovy: how to use variables in regex pattern find-counts?

In the following declarative syntax pipeline:

pipeline {
  agent any
  stages {
    stage( "1" ) {
      steps {
        script {
          orig = "/path/to/file"
          two_lev_down = (orig =~ /^(?:\/[^\/]*){2}(.*)/)[0][1]
          echo "${two_lev_down}"
          depth = 2
          two_lev_down = (orig =~ /^(?:\/[^\/]*){depth}(.*)/)[0][1]
          echo "${two_lev_down}"
        }
      }
    }
  }
}

...the regex is meant to match everything after the third instance of "/".
The first, i.e. (orig =~ /^(?:\/[^\/]*){2}(.*)/)[0][1] works.
But the second, (orig =~ /^(?:\/[^\/]*){depth}(.*)/)[0][1] does not. It generates this error:

java.util.regex.PatternSyntaxException: Illegal repetition near index 10
^(?:/[^/]*){depth}(.*)

I assume the problem is the use of the variable depth instead of a hardcoded integer, since that's the only difference between the working code and error-generating code.

How can I use a Groovy variable in a regex pattern find-count? Or what is the Groovy-language idiomatic way to write a regex that returns everything after the nth occurrence of a pattern?

Upvotes: 2

Views: 9812

Answers (1)

injecteer
injecteer

Reputation: 20699

You are missing the $ in front of your variable. It should be:

orig = "/path/to/file"
depth = 2           
two_lev_down = (orig =~ /^(?:\/[^\/]*){$depth}(.*)/)[0][1]

assert '/file' == two_lev_down 

Why?

In Groovy the String-interpolation (over GString) works for 3 String literals:

  1. usual double quotes: "Hello $world, my name is ${name.toUpperCase()}"
  2. Slashy-strings used usually as regexp-literals: /.{$depth}/
  3. Multi-line double-quoted Strings:
def email = """
Dear ${user}.
Thank your for blablah.
""" 

Upvotes: 5

Related Questions