Home > Back-end >  how to use ansible regex to display nth matches
how to use ansible regex to display nth matches

Time:11-17

I am trying to use ansible regex_search to get the value in ansible tasks.

Full string:

VRP (R) software, Version 5.170 (S5735 V200R019C00SPC500)

String that I want to match:

V200R019C00SPC500

So I am trying to match the second parenthesis , second fields after a space.
This assume the value is always different hence I will not try to match V200 or any of the string.

I have tried a few methods but all is not working, kindly advise which one is better and more accurate.

Here is the regex101.

As you can see the string i wanted to match is in "Match 2". However when translate into ansible it will only print the first match, i.e (R)

ansible tasks:

  - debug:
      msg:
      - "{{ displayversion |regex_search('[(].*?.[)]') }}"
      - "{{ displayversion |regex_search('\\(([^)] )?([^)])\\)') }}"
      - "{{ displayversion |regex_search('^(. )\\s(. )', '\\2')  }}"
    vars:
      displayversion: VRP (R) software, Version 5.170 (S5735 V200R019C00SPC500)

will get

ok: [localhost] => {
    "msg": [
        "(R)",
        "(R)",
        [
            "V200R019C00SPC500)"
        ]
    ]
}

The 3rd options is the closest one, but it still have the parenthesis and is a list , I would also like to know how to remove it within the same regex.

Thanks

CodePudding user response:

You can use a capture group, and match the second part after the space between parenthesis:

\([^()\s]*\s([^()\s] )\)
  • \( Match the opening (
  • [^()\s]* Optionally match any char except ( ) or a whitespace char
  • \s Match a whitspace char
  • ( Capture group 1
    • [^()\s] Match 1 chars other than ( ) or \s
  • ) Close group 1
  • \) Match the closing )

With the doubled backslashes

\\([^()\\s]*\\s([^()\\s] )\\)

See a regex demo.

Using regex_search you can specify which group to return from the match, which will be group 1 using \\1

{{ displayversion |regex_search('\\([^()\\s]*\\s([^()\\s] )\\)', '\\1') | first }}

CodePudding user response:

You can use

"{{ displayversion | regex_search('\\w (?=\\W*$)')  }}"

See this regex demo. Details:

  • \w - one or more word chars
  • (?=\W*$) - followed with zero or more non-word chars at the end of string.

This is basically extracting the last "word" (a chunk of letters, digits, underscores) in the string.

If you need to check this word occurs right before the ) at the end of string, use "{{ displayversion | regex_search('\\w (?=\\)$)') }}".

CodePudding user response:

With your shown samples, please try following regex.

\bVRP\s \(R\)\s software,\s Version\s \d (?:\.\d \s )?\(\S \s ([^)]*)\)

Online demo for above regex

Explanation: Adding detailed explanation for above regex.

\bVRP\s \(R\)\s      ##putting a word boundary followed by VRP followed by 1 or more spaces followed by (R) followed by spaces 1 or more occurrences.
software,\s Version  ##Matching software, followed by spaces followed by Version.
\s \d (?:\.\d \s )?  ##Matching spaces followed by digits and matching optional dot digits too here, to match both 5 OR 5.170 kind of values.
\(\S \s              ##Matching ( followed by non-spaces followed by spaces.
([^)]*)              ##Creating 1st an only capturing group which has everything till ) here in it.
\)                   ##Matching ) here, to make sure to get values between (...) only.
  • Related