Replace version in yaml structure with regexp

Viewed 337

I'm trying to replace the value of the version property in the following yaml structure.

My reason for using regex rather than parsing the yaml is that I need to write it back again. If I parse it and then write it back it'll loose it's existing formatting.

environments:
  local:
    values:
      - kubeContext: default
      - surfScreenshotter:
          installed: false
          version: 0
      - whoamiMn:
          installed: false
          version: 0
  dev:
    values:
      - kubeContext: nuc
      - surfScreenshotter:
          installed: false
          version: 0
      - whoamiMn:
          installed: false
          version: 0

My kotlin code

val regex = """environments:
    |.*
    |  $environment:
    |    values:
    |.*
    |      - $projectName:
    |.*
    | {10}version: (\S+)
""".trimMargin().toRegex(MULTILINE)
val updatedHelmfile = regex.replaceFirst(helmfileContent, version)

$environment can be either "local" or "dev" and projectName can be "surfScreenshotter" or "whoamiMn".

Nothing is matched. Anyone got an idea how to make this work?

1 Answers

You can rely on indentation to make sure you are in the right section of your text block and capture the whole part before the version into a capturing group:

val regex = """(environments:
    |(?:\R\h{2}.*)*?\R\h{2}$environment:
    |(?:\R\h{4}.*)*?\R\h{6}-\h*$projectName:
    |(?:\R\h{10}.*)*?\R\h{10}
    |version:\h*)\S+
""".trimMargin().toRegex(RegexOption.COMMENTS)

Then, you need to make sure to restore Group 1 contents with $1 in the replacement pattern:

val updatedHelmfile = regex.replaceFirst(helmfileContent, "$1" + version)

See the regex demo and the Kotlin demo.

Details

  • (environments: - Group 1 start and environments: string
  • (?:\R\h{2}.*)*?\R\h{2}dev: - zero or more occurrences (as few as possible) of a line break followed with two horizontal whitespace and then the rest of the line, then a line break, two horizontal whitespace and dev: string
  • (?:\R\h{4}.*)*?\R\h{6}-\h*whoamiMn: - zero or more occurrences (as few as possible) of a line break followed with four horizontal whitespace and then the rest of the line, then a line break, six horizontal whitespace and - + 0 or more spaces, and then whoamiMn: string
  • (?:\R\h{10}.*)*?\R\h{10} - zero or more occurrences (as few as possible) of a line break followed with ten horizontal whitespace and then the rest of the line, then a line break, ten horizontal whitespace
  • version:\h*) - version:, 0 or more spaces, end of Group 1
  • \S+ - one or more non-whitespace chars.
Related