Turns out Python doesn't support repeated named capture groups unlike .NET, which is a bit of a shame (means my solution is a little longer than I thought it'd need to be). Does this meet your requirements?
import re
def is_valid(s):
pattern = '^name\d+,value\d+(,tag\d+=value\d+)*$'
return re.match(pattern, s)
def get_name_value_pairs(s):
if not is_valid(s):
raise ValueError('Invalid input: {}'.format(s))
pattern = '((?P<name1>\w+),(?P<value1>\w+))|(?P<name2>\w+)=(?P<value2>\w+)'
for match in re.finditer(pattern, s):
name1 = match.group('name1')
name2 = match.group('name2')
value1 = match.group('value1')
value2 = match.group('value2')
if name1 and value1:
yield name1, value1
elif name2 and value2:
yield name2, value2
if __name__ == '__main__':
testString = 'name1,value1,tag11=value11,tag12=value12,tag13=value13'
assert not is_valid('')
assert not is_valid('foo')
assert is_valid(testString)
print(list(get_name_value_pairs(testString)))
Output
[('name1', 'value1'), ('tag11', 'value11'), ('tag12', 'value12'), ('tag13', 'value13')]
Edit 1
Added input validation logic. Assumptions made:
- Must have initial name/value pair in form
name<x>,value<x>
- All following pairs must be in form
tag<x>=value<x>
- Names and values consist only of alphanumeric characters
- Whitespace is not allowed
Note that I'm not currently validating that x is the same value within a name/value pair, which I assume is a requirement. I'm not sure how to do this leaving this as an exercise for the reader.
((?<name>\w+),(?<value>\w+))|(?<name>\w+)=(?<value>\w+)(tested on RegExr sans the named capture groups).