andrei
andrei

Reputation: 965

Regex non-greedy OR

Say I have 3 regular expressions A, B and C.

I need to match either A and B together or separately but always at least one. C is optional.

My combined regex so far is A?B?C but if A and B doesn't match it still works. I've tried A|BC however if A is matched, B is not evaluated and I need it to be evaluated.

(?P<param1>\d+)?(?P<param2>+\d+)?(?P<param3>\w+)

Any ideas?

Upvotes: 2

Views: 97

Answers (3)

Peter DeGlopper
Peter DeGlopper

Reputation: 37354

Ugly as it is, maybe this would work?

(?P<possibly_joined_params>\d+\+\d+|\d+|\+\d+)(?P<param3>\w+)?

And then in your view, try splitting on '+':

def someview(request, possibly_joined_params, param3=None):
    param_parts = possibly_joined_params.split('+')
    if len(param_parts) == 1:
        param1 = param_parts[0]
        param2 = ''
    else:
        param1, param2 = param_parts

I'm not sure that's cleaner than the idea of just having two patterns to match the view, though.

Upvotes: 0

Ωmega
Ωmega

Reputation: 43683

Use regex pattern

(?:A(?:B)?|B)(?:C)?

UPDATE:

If you need to use each of A, B and C only once, go with

((?:A)?(?:B)?)(?!\1{100})(?:C)?

which is not 100% correct, but should cover 99.99+% of all possibilities

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1124110

You could match three alternatives: (AB|A|B), but this does require that you capture 4 different groups; two for the A and B case, and one each for the A or B cases. Your code extracting the captured groups will have to take this into account:

(?:(?P<param1_and>\d+)(?P<param2_and>+\d+)|(?P<param1_or>\d+)|(?P<param2_or>+\d+))(?P<param3>\w+)

and you'd have to look for param1_and or param1_or and param2_and or param2_or in the captured groups.

Upvotes: 0

Related Questions