a p
a p

Reputation: 3208

Regex named conditional lookahead (in Python)

I'm hoping to match the beginning of a string differently based on whether a certain block of characters is present later in the string. A very simplified version of this is:

re.search("""^(?(pie)a|b)c.*(?P<pie>asda)$""", 'acaaasda')

Where, if <pie> is matched, I want to see a at the beginning of the string, and if it isn't then I'd rather see b.

I'd use normal numerical lookahead but there's no guarantee how many groups will or won't be matched between these two.

I'm currently getting error: unknown group name. The sinking feeling in my gut tells me that this is because what I want is impossible (look-ahead to named groups isn't exactly a feature of a regular language parser), but I really really really want this to work -- the alternative is scrapping 4 or 5 hours' worth of regex writing and redoing it all tomorrow as a recursive descent parser or something.

Thanks in advance for any help.

Upvotes: 1

Views: 1369

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89614

You can use something like that:

^(?:a(?=c.*(?P<pie>asda)$)|b)c.*$

or without .*$ if you don't need it.

Upvotes: 1

Sean Vieira
Sean Vieira

Reputation: 160043

Unfortunately, I don't think there is a way to do what you want to do with named groups. If you don't mind duplication too much, you could duplicate the shared conditions and OR the expressions together:

^(ac.*asda|bc.*)$

If it is a complicated expression you could always use string formatting to share it (rather than copy-pasting the shared part):

common_regex = "c.*"
final_regex = "^(a{common}asda|b{common})$".format(common=common_regex)

Upvotes: 4

Related Questions