Java regex: Repeating capturing groups

An item is a comma delimited list of one or more strings of numbers or characters e.g.

"12"
"abc"
"12,abc,3"

I'm trying to match a bracketed list of zero or more items in Java e.g.

""
"(12)"
"(abc,12)"
"(abc,12),(30,asdf)"
"(qqq,pp),(abc,12),(30,asdf,2),"

which should return the following matching groups respectively for the last example

qqq,pp
abc,12
30,asdf,2

I've come up with the following (incorrect)pattern

\((.+?)\)(?:,\((.+?)\))*

which matches only the following for the last example

qqq,pp
30,asdf,2

Tips? Thanks


That's right. You can't have a "variable" number of capturing groups in a Java regular expression. Your Pattern has two groups:

\((.+?)\)(?:,\((.+?)\))*
  |___|        |___|
 group 1      group 2

Each group will contain the content of the last match for that group. I.e., abc,12 will get overridden by 30,asdf,2.

Related question:

  • Regular expression with variable number of groups?

The solution is to use one expression (something like \((.+?)\)) and use matcher.find to iterate over the matches.


You can use regular expression like ([^,]+) in loop or just str.split(",") to get all elements at once. This version: str.split("\\s*,\\s*") even allows spaces.


(^|\s+)(\S*)(($|\s+)\2)+ with ignore case option /i

She left LEft leFT now

example here - https://regex101.com/r/FEmXui/2

Match 1
Full match  3-23    ` left LEft leFT LEFT`
Group 1.    3-4 ` `
Group 2.    4-8 `left`
Group 3.    18-23   ` LEFT`
Group 4.    18-19   ` `