0

I'm trying to use regex to pull just the patch version out of some semvars in the form v1.2.3

I've got some regex which can match the v1.2. part however I'm struggling to get the other part, the 3 (which I actually want back)

I'm using ^v\d+\.\d+\. to select the first part.

I'm trying to use a negative lookahead with this to then select everything after it with (?!(v\d+\.\d+\.)).* but this just seems to return everything after the v rather than everything after the group

Any pointers would be really appreciated, thanks!

1 Answers1

1

In this special case:

'^(?<=v\d\.\d\.)[[:alnum:]]+'

The regular expression matches as follows:

Node Explanation
^ start of string
(?<= look behind to see if there is:
v v
\d digits (0-9)
\. .
\d digits (0-9)
\. .
) end of look-behind
[[:alnum:]]+ any character of: letters and digits (1 or more times (matching the most amount possible))

A more generic solution than works with any length of digits

'^v\d+\.\d+\.\K.[[:alnum:]]+'

The regular expression matches as follows:

Node Explanation
^ start of string
v v
\d+ digits (0-9) (1 or more times (matching the most amount possible))
\. .
\d+ digits (0-9) (1 or more times (matching the most amount possible))
\. .
\K resets the start of the match (what is Kept) as a shorter alternative to using a look-behind assertion: look arounds and Support of K in regex
[[:alnum:]]+ any character of: letters and digits (1 or more times (matching the most amount possible))

Check man tr | grep -FA1 '[:' for a POSIX character classes like [[:alnum:]]

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • Can the patch version be something else than a number? I mean something like `v2.10.a` instead of `v2.10.458` ? In any case, I would prefer not using `.*` at the end as it matches spaces or any other char which could not be a patch number. So I would replace `.*` by `\d+` or eventually `[\da-z]+`. – Patrick Janser Feb 14 '23 at 10:06