If we want to match a list of any kind in regex, we currently have to make certain compromises. For example, say we wanted to match a list of names, such as: Anna,Bob,Charlie (a more complex example would be a list of phone numbers, or url's, so imagine the regex is potentially long and complex).
We could try:
((Anna|Bob|Charlie),)+
However that doesn't match our original text as it requires a final , to match.
| Text | Should match | Matches |
| --- | --- | --- |
| "Anna,Bob,Charlie" | yes | no (wrong) |
| "AnnaBob,Charlie" | no | no |
We could try:
((Anna|Bob|Charlie),?)+
But this will wrongly match items without the separator, which is probably not what the user wants:
| Text | Should match | Matches |
| --- | --- | --- |
| "Anna,Bob,Charlie" | yes | yes |
| "AnnaBob,Charlie" | no | yes (wrong) |
Currently the only way to achieve this is through the duplication of the list-item regex group:
(Anna|Bob|Charlie)(,(Anna|Bob|Charlie))*
Which is a pain when the match is long like a phone number or a url, and if you update one part you have to remember to copy the changes to the other one. It also gets tricky if say you wanted it to match from 0 to 20 items, you'd have to do it like this:
((Anna|Bob|Charlie)(,(Anna|Bob|Charlie)){0,19})?
The only way to somewhat avoid this is to put that regex part into a variable and use the variable twice to construct the regex, but this relies on the host language, still creates a longer than necessary regex, and matches an extra redundant matching group which the user then has to manually group with the first in the host language.
A more useful approach could be to use some repetition separator syntax. Regex already has repetition quantifiers like +, *, ? and also {m,n}. The last one could be enhanced to specify an optional third parameter as a repetition-separator group:
(Anna|Bob|Charlie){0,20,(,)}
Since it can contain any valid regex syntax, it should always be enclosed inside a group, and it behaves like any normal group. Just like in normal usage, the quantifier limit values can be missing entirely:
(Anna|Bob|Charlie){,,(,)}
And if we only wanted to specify the separator:
(Anna|Bob|Charlie){(,)}
This would allow infinite repetition, equivalent to using the * or {,} quantifiers.
| Text | Should match | Matches |
| --- | --- | --- |
| "Anna,Bob,Charlie" | yes | yes |
| "AnnaBob,Charlie" | no | no |
We could then easily enhance it to, for example, allow spaces after each comma:
(Anna|Bob|Charlie){(, *)}
This is much shorter and more readable than any existing alternatives, and produces a match result with all the correct values in the same matching group. The flow would look like this:

These examples have been kept short for readability reasons and could need fine-tuning to work in all cases.
| Description | Regex |
| --- | --- |
| Phone number lists | (\(?\d{3}\)?-? *\d{3}-? *-?\d{4}){(, *)} |
| Versions names ("3.7.15") | (\d){(\.)} |
| Html class attribute | class="\s*(?<class>\S+){(\s+)}\s*" |
| Html class attribute (alternative) | class="(\s*){(?<class>\S+)}" |
| Mathematical calculations ("7.5 * 2 + 10") | (\d+(\.\d)?([Ee]\d)?){( *[+-*/] *)} |
| Name parts ("Johann Wolfgang von Goethe") | ^(?<part>\S+){( )}$ |
| Natural language (notice the nested repetitions) | winners are (?<name>(?<name_part>\S+){1,,( )}){( then )} |
| Time matching ("03:15", "23:59:59") | (\d\d):(\d\d){1,2,(:)} |
| Javascript object notation | [{] *(?<key>[a-zA-Z_]\w*) *: *(?<value>"[^"]*"|\d+(\.\d*)?([Ee]\d*)?|...other.types..){( *, *)} *[}] |
In certain use cases a final optional separator match is also desirable. For example, in C# the collection initializer syntax allows for an optional final ,:
``` C#
var names = new List
"Anna Alyson",
"Bob Borton",
"Charlie Cob",
};
For this we could further enhance the syntax so that if the separator-group has a `+` after it, it can have an optional final match (the separator-group would not allowed to have any other quantifiers, however sub-groups can). The regex would look like this:
[{]\s(?
```
The new flow would then look like this:

Are there any other regex dialects that support behavior like this? Regular expressions being a somewhat standard language I'd be loathe to see .NET extend the core syntax in such a manner.
The requested feature is a proposal for a new syntax in Regex language rather than the Regex API in .NET. We do have ways to accomplish matching these kind of patterns with the current syntax, and the proposal is to have a simplified way. There is a POSIX standard for regular expressions, and due to its limitations, .NET implements the Perl 5 regex syntax. This proposal would be better suited to extend to those standards first, before .NET APIs support it.
Most helpful comment
The requested feature is a proposal for a new syntax in Regex language rather than the Regex API in .NET. We do have ways to accomplish matching these kind of patterns with the current syntax, and the proposal is to have a simplified way. There is a POSIX standard for regular expressions, and due to its limitations, .NET implements the Perl 5 regex syntax. This proposal would be better suited to extend to those standards first, before .NET APIs support it.