0

Similar to questions How to capture multiple repeated groups?, or How to iterate over the matched groups of a regular expression, but I can't seem to wrap my head around if its slightly different.. Seems like most folks want to cycle through the instances of the matches within the string, rather than cycle through the Groups that the string matches.

I have a compiled regular expression, with multiple groups in it - each with an OR between them.. My regular expression looks like this:

self.combined_re = re.compile('|(?P<a0>/T/R/E/Relation)|(?P<a1>/T/R/E/Relation)|(?P<a2>/T/R/E/Relation/Orig)|(?P<a3>/T/R/E/Relation)|(?P<a4>/T/R/E/Relation/Related)|(?P<a5>/T/R/E/Relation/Role)|(?P<a6>/T/R/E/Relation/Volume)')

Note that the above is an example - my regular expressions are dynamically created, but this is just an example. Its a slightly more obvious regular expression with only exact strings, for the sake of simplicity..

If I run

match_object = self.combined_re.fullmatch("/T/R/E/Relation")

you can see that groups a0, a1, and a3 will ALL match this one string...

How can I cycle through these 3 groups (not knowing they will be the ones matched)? Ugly pseudo code to try and show an example as to how I'd use it:

for each matched group in match_object:
 if matched group = a0:
   do a0 stuff
 elsif matched group = a1:
   do a1 stuff
 ...
 elsif matched group = a6:
   do a6 suff

I am currently using the

match_object.lastgroup

call, but of course this just gives me one of the groups and I lose the others. Is there no way to do this with match objects? I would really prefer not to change my re .. hoping this can be done with some match object things I am missing.. Thanks!

da Bich
  • 494
  • 1
  • 4
  • 13
  • or does the fullmatch call just stop at the first group matching, and so it doesn't even know there are others? is there maybe a different method to call which would test every group without me having to create separate re's for each? – da Bich Jul 06 '21 at 04:29
  • i have tried match_object.groupdict() now.. it gets me nearly there as it does show me the group that matched.. but it seems to stop at the first match as I feared. Maybe if i use a different call from fullmatch, there is one that would test every group? – da Bich Jul 07 '21 at 00:58
  • confirmed.. from https://docs.python.org/3/library/re.html#regular-expression-syntax : | creates a regular expression that will match either A or B. An arbitrary number of REs can be separated by the '|' in this way. This can be used inside groups (see below) as well. As the target string is scanned, REs separated by '|' are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once A matches, B will not be tested further, even if it would produce a longer overall match. In other words, the '|' operator is never greedy." I Need it GREEDY – da Bich Jul 07 '21 at 01:04

1 Answers1

1

Appears it is not possible to have a regex with multiple groups and force the matching to tell you ALL the groups that matched the string. Using the | between groups is not greedy, so it stops as soon as first group matches. without the |, the groups must all satisfy the string.

So only option for me was to separate out all my groups into separate regex's and execute each individually.

Let me know if you know another way.

da Bich
  • 494
  • 1
  • 4
  • 13