sharadendu sinha sharadendu sinha - 6 months ago 17
Java Question

Regex capturing sub groups with exact and partial matches

I have

input string :
$data.store.author_handle.name0_handle[*].some.min()
regex :
^\$([a-zA-Z_0-9]+)(.[a-zA-Z_0-9.]+[\[\*0-9\]]*[.a-zA-Z_0-9]*)(.[min\(\)]*$)


So I get groups as follows


  1. data

  2. .store.author_handle.name0_handle[*].some.min

  3. ()



Where as I want to capture as below


  1. data

  2. .store.author_handle.name0_handle[*].some

  3. .min()



Please note input can take the forms

$<literal>.<json path> <aggregator function>
<aggregator function> is optional and can be min/max/avg
<literal> : ([a-zA-Z_0-9]+)


Json path is any that is allowed by https://github.com/jayway/JsonPath

Answer

You can use following regex

^\$([\w]+)(\..+?)((?:\.(?:min|max|avg)\(\))?$)

Regex Demo

Regex Breakdown

^ #start of string
\$ #Match $ literally

( #Start of 1st capturing group
  [\w]+ #Match characters in set [A-Za-z0-9_] at least once(you can also use [^.]+)
) #End of 1st capturing group

( #Start of 2nd capturing group
  \. #Match . literally
  .+? #Match lazily till next condition is met
) #End of 2nd capturing group

( #Start of 3rd capturing group
  (?: #Non capturing group
    \. #Match . literally
      (?: #Non capturing group
         min|max|avg #Match any from min,max or avg
      )
    \(\) #Match () literally
  )? #As mentioned, this all can be optional(aggregation part)
  $ #End of string(Kept here so that if nothing matches 0 sized string is returned instead of null)
) #End of 3rd capturing group

or

^\$([\w]+)(\..+?)((?:\.(?:(?:\w+)\(\)))?$)

for generalized aggregation function

Ideone Demo