Jeff
Jeff

Reputation: 53

Optional group doesn't match anything

I use the following regex, but it doesn't work

([^@]+)(?:_@(\d+))?

Variable_Name_1
Actual:
\1 = Variable_Name_1
\2 = null

Expected:

\1 = Variable_Name_1
\2 = null

Variable_Name_1_@4
Actual:

\1 = Variable_Name_1_
\2 = null

Expected:

\1 = Variable_Name_1
\2 = 4

Do you have some ideas to solve my problem ?

Upvotes: 0

Views: 106

Answers (2)

bgporter
bgporter

Reputation: 36584

If that's the only requirement, regular expressions are overkill. How about this instead:

>>> "variable_name_1".partition("_@")
('variable_name_1', '', '')
>>> "variable_name_2_@5".partition("_@")
('variable_name_2', '_@', '5')

Upvotes: 3

Irfy
Irfy

Reputation: 9607

Your regex matches the first kind of string properly, but does not match the second kind properly.

Removing the last ? in your regex matches the second kind of string properly, but no longer matches the first one properly.

I believe the reason is that making the second part of the regex optional, makes the first part too greedy. I do not know if there is a modifier that will make your regex work, but a combination of the two regexes will work:

>>> re.search('(?:([^@]+)(?:_@(\d+))|([^@]+))', 'Variable_Name_1_@4').groups()
('Variable_Name_1', '4', None)
>>> re.search('(?:([^@]+)(?:_@(\d+))|([^@]+))', 'Variable_Name_1').groups()
(None, None, 'Variable_Name_1')

What you need now is just post-process the tuple to have two elements where second is maybe None.

Alternatively, you could manually try matching against the first regex, and then against the second regex in a utility function.

Upvotes: 0

Related Questions