简体   繁体   中英

non-greedy regex capture groups syntax

given the following text

key: foo/bar:v1.2.3
    key: baz/spam:1.2.3 greedy

i have tried the following regex:

^\s*key: (?<ref>.*?):(?<ver>.*)

which returns the following groups ( demo ):

  • ref: foo/bar, ver: v1.2.3
  • ref: baz/spam, ver: 1.2.3 greedy

what is missing from the regex in order to match\group the version (eg 1.2.3 ) without the preceding text (eg greedy )?

Since you are using .* in your last capture group, it is matching everything till the end of of line in 2nd capture group.

You could restrict matching of your regex to match only non-whitespace characters by using \S (which is opposite of \s and it matches any character other that whitespaces):

^\s*key: (?<ref>[^:]+):(?<ver>\S+)

Also note use of a negated character class [^:] in 1st capture group to reduce backtracking which matches any character other than : .

RegEx Demo

Another option to match the version number is to match the digits separated by a dot with an optional v char.

^\s*key: (?<ref>[^:]+):(?<ver>v?\d+(?:\.\d+)*)\b
  • ^ Start of string
  • \s*key: Match optional whitespace chars and key:
  • (?<ref>[^:]+) Capture group ref match 1+ chars other than :
  • :v? Match : and optional v
  • (?<ver> Capture group ver
    • \d+(?:\.\d+)* Match 1+ digits and optionally repeat the dot and digits
  • ) Close group ver
  • \b A word boundary

Regex demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM