Search code examples
regexansible

Ansible regex replace matching but exclude other match in same line


Below lines in configuration file to be replaced with java path, but do not replace java where you have java.base and java.lang.

  1. JAVA_VERSION=$("java" -version 2>&1 | awk -F '"' '/version/ {print $2}')

  2. $java -DagentVersion=2.6.0 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -jar

tried below in ansible task

- replace:
  path: "/tmp/config.txt"
  regexp: '^(?!.*java[.])(?=java)(.*)$'
  replace: '/opt/java17\1'

Expected output : replaced java in both lines with /opt/java17 but do not edit & exclude java matched in the area (java.base/java.lang) of same line.

  1. JAVA_VERSION=$("/opt/java17" -version 2>&1 | awk -F '"' '/version/ {print $2}')

  2. $/opt/java17 -DagentVersion=2.6.0 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -jar


Solution

  • Try:

    \bjava\b(?!\.)
    

    See: regex101


    Explanation

    • \b: Matches a word boundary
    • java: Matches literal "java"
    • \b: Matches word boundary
    • (?!\.): Checks, that "java" is not followed by a literal "."

    Your construct of (?=java) finds "java", but then your construct of (?!.*java) matches "java" also and thus fails at the spot where you would have wanted to match, since ".*" can match 0 characters.