Barry
Barry

Reputation: 303397

Key=Val matching using regex

I want to match either key or key=val in python such that the resulting groupdict() from the Match object will either have val as None or have a value.

The following is close:

>>> regex = re.compile('(?P<key>[^=]+)=?(?P<val>.*)')
>>> regex.match('x=y').groupdict()
{'key': 'x', 'val': 'y'}            # yes!
>>> regex.match('x').groupdict()
{'key': 'x', 'val': ''}             # want None, not ''

But I want val to be None in the second case. I tried moving the optional = into the second group:

>>> regex = re.compile('(?P<key>[^=]+)(?P<val>=.+)?')
>>> regex.match('x').groupdict()
{'key': 'x', 'val': None}           # yes!
>>> regex.match('x=y').groupdict()
{'key': 'x', 'val': '=y'}           # don't want the =

That gives me the None, but then attaches the = to val. I also tried using the lookbehind with (?<==) but that didn't work for either expression. Is there a way to achieve this?

Upvotes: 1

Views: 141

Answers (2)

Vaibhav Gupta
Vaibhav Gupta

Reputation: 401

Try this:

regex = re.compile('(?P<key>[^=]+)(?:=(?P<val>.*))?')

Edited the regex

Test 1 : 'x=y' , then key='x' and val='y'

Test 2 : 'x=' , then key='x' and val=''

Test 3 : 'x' , then key='x' and val=None

Upvotes: 0

nu11p01n73R
nu11p01n73R

Reputation: 26667

Add an optional quantifier ? to the value part so that it is matched zero or one time

>> regex = re.compile('(?P<key>[^=]+)(?:=(?P<val>.+))?')
>>> regex.match('x=y').groupdict()
{'key': 'x', 'val': 'y'}
>>> regex.match('x').groupdict()
{'key': 'x', 'val': None}

Changes made

  • Moved the = to a non capturing group (?:..)

  • (?:=(?P<val>.+))? Matched zero or one time. This is ensured by the ?. That is it checks if =value can be matched (capturing only the value part). If not None is captured.

Upvotes: 3

Related Questions