You could create a little class that returns the boolean result of calling match, and retains the matched groups for subsequent retrieval:

import re

class REMatcher(object):
    def __init__(self, matchstring):
        self.matchstring = matchstring

    def match(self,regexp):
        self.rematch = re.match(regexp, self.matchstring)
        return bool(self.rematch)

    def group(self,i):
        return self.rematch.group(i)


for statement in ("I love Mary", 
                  "Ich liebe Margot", 
                  "Je t'aime Marie", 
                  "Te amo Maria"):

    m = REMatcher(statement)

    if m.match(r"I love (\w+)"): 
        print "He loves",m.group(1) 

    elif m.match(r"Ich liebe (\w+)"):
        print "Er liebt",m.group(1) 

    elif m.match(r"Je t'aime (\w+)"):
        print "Il aime",m.group(1) 

    else: 
        print "???"

Update for Python 3 print as a function, and Python 3.8 assignment expressions - no need for a REMatcher class now:

import re

for statement in ("I love Mary",
                  "Ich liebe Margot",
                  "Je t'aime Marie",
                  "Te amo Maria"):

    if m := re.match(r"I love (\w+)", statement):
        print("He loves", m.group(1))

    elif m := re.match(r"Ich liebe (\w+)", statement):
        print("Er liebt", m.group(1))

    elif m := re.match(r"Je t'aime (\w+)", statement):
        print("Il aime", m.group(1))

    else:
        print()
Answer from PaulMcG on Stack Overflow
🌐
Python documentation
docs.python.org › 3 › howto › regex.html
Regular Expression HOWTO — Python 3.14.3 documentation
The match object methods that deal with capturing groups all accept either integers that refer to the group by number or strings that contain the desired group’s name. Named groups are still given numbers, so you can retrieve information about a group in two ways: >>> p = re.compile(r'(?P<word>\b\w+\b)') >>> m = p.search( '(((( Lots of punctuation )))' ) >>> m.group('word') 'Lots' >>> m.group(1) 'Lots'
🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations
4 days ago - Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. Group names must be valid Python identifiers, and in bytes patterns they can only contain bytes in the ASCII range. Each group name must be defined only once within a regular ...
Discussions

regex - Match groups in Python - Stack Overflow
Releases Keep up-to-date on features we add to Stack Overflow and Stack Internal. ... Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... Is there a way in Python to access match groups ... More on stackoverflow.com
🌐 stackoverflow.com
regex - Capture groups with Regular Expression (Python) - Stack Overflow
I'm learning regular expressions and am on this lesson: https://regexone.com/lesson/capturing_groups. In the python interpreter, I try to use the parentheses to only capture what precedes the .pdf part of the search string but my result captures it despite using the parens. More on stackoverflow.com
🌐 stackoverflow.com
(Regex | Regular expression) match.group(1) = 'None' due to using appended patterns
I'm not sure if reddit messed up your code or something, but there seems some missing escapes in the regex (e.g. d+ rather than \d+). Secondly, there's something strange, 1x300g does not match the pattern you provided, since it requires at least one whitespace character after the 'x'. The groups when there are alternatives are not independent. For example, in the regex a(\d)|b(\d) there are two groups, group(1) would be the digit after an 'a', and group(2) would be the digit after a 'b'. group(0) is always the entire match. e.g. >>> re.search("a(\d)|b(\d)", "a1").groups() ('1', None) >>> re.search("a(\d)|b(\d)", "b1").groups() (None, '1') The built-in 're' module does not support overlapping groups, but you can name them: >>> re.search("a(?P\d)|b(?P\d)", "a1").groupdict() {'adigit': '1', 'bdigit': None} >>> re.search("a(?P\d)|b(?P\d)", "b1").groupdict() {'adigit': None, 'bdigit': '1'} So you can first figure out whether you are in the 'a' or 'b' case, then access the correct group. The third-party 'regex' package does support overlapping groups, which means you can make code a bit more robust: >>> import regex >>> regex.search("a(?P\d)|b(?P\d)", "a1").groupdict() {'digit': '1'} >>> regex.search("a(?P\d)|b(?P\d)", "b1").groupdict() {'digit': '1'} More on reddit.com
🌐 r/learnpython
6
8
December 19, 2024
Accessing a "symbolic group name" in Python regex
You use them with Match objects. findall doesn't return those, it returns strings only. For what you want, you would need to use finditer which does return Match objects. However, this is a generator so you couldn't index it, but you can iterate it: for match in found: print(f'Data Content:\t{match["value"]}') More on reddit.com
🌐 r/learnpython
6
1
November 28, 2022
🌐
GeeksforGeeks
geeksforgeeks.org › python › re-matchobject-group-function-in-python-regex
re.MatchObject.group() function in Python Regex - GeeksforGeeks
July 15, 2025 - If we pass an invalid group number in the method argument then we will get an IndexError exception. ... import re """We create a re.MatchObject and store it in match_object variable the '()' parenthesis are used to define a specific group""" match_object = re.match(r'(\w+)@(\w+)\.(\w+)', 'username@geekforgeeks.org') """ w in above pattern stands for alphabetical character + is used to match a consecutive set of characters satisfying a given condition so w+ will match a consecutive set of alphabetical characters""" # Following line will raise IndexError exception print(match_object.group(7))
Top answer
1 of 5
78

You could create a little class that returns the boolean result of calling match, and retains the matched groups for subsequent retrieval:

import re

class REMatcher(object):
    def __init__(self, matchstring):
        self.matchstring = matchstring

    def match(self,regexp):
        self.rematch = re.match(regexp, self.matchstring)
        return bool(self.rematch)

    def group(self,i):
        return self.rematch.group(i)


for statement in ("I love Mary", 
                  "Ich liebe Margot", 
                  "Je t'aime Marie", 
                  "Te amo Maria"):

    m = REMatcher(statement)

    if m.match(r"I love (\w+)"): 
        print "He loves",m.group(1) 

    elif m.match(r"Ich liebe (\w+)"):
        print "Er liebt",m.group(1) 

    elif m.match(r"Je t'aime (\w+)"):
        print "Il aime",m.group(1) 

    else: 
        print "???"

Update for Python 3 print as a function, and Python 3.8 assignment expressions - no need for a REMatcher class now:

import re

for statement in ("I love Mary",
                  "Ich liebe Margot",
                  "Je t'aime Marie",
                  "Te amo Maria"):

    if m := re.match(r"I love (\w+)", statement):
        print("He loves", m.group(1))

    elif m := re.match(r"Ich liebe (\w+)", statement):
        print("Er liebt", m.group(1))

    elif m := re.match(r"Je t'aime (\w+)", statement):
        print("Il aime", m.group(1))

    else:
        print()
2 of 5
33

Less efficient, but simpler-looking:

m0 = re.match("I love (\w+)", statement)
m1 = re.match("Ich liebe (\w+)", statement)
m2 = re.match("Je t'aime (\w+)", statement)
if m0:
  print("He loves", m0.group(1))
elif m1:
  print("Er liebt", m1.group(1))
elif m2:
  print("Il aime", m2.group(1))

The problem with the Perl stuff is the implicit updating of some hidden variable. That's simply hard to achieve in Python because you need to have an assignment statement to actually update any variables.

The version with less repetition (and better efficiency) is this:

pats = [
    ("I love (\w+)", "He Loves {0}" ),
    ("Ich liebe (\w+)", "Er Liebe {0}" ),
    ("Je t'aime (\w+)", "Il aime {0}")
 ]
for p1, p3 in pats:
    m = re.match(p1, statement)
    if m:
        print(p3.format(m.group(1)))
        break

A minor variation that some Perl folk prefer:

pats = {
    "I love (\w+)" : "He Loves {0}",
    "Ich liebe (\w+)" : "Er Liebe {0}",
    "Je t'aime (\w+)" : "Il aime {0}",
}
for p1 in pats:
    m = re.match(p1, statement)
    if m:
        print(pats[p1].format(m.group(1)))
        break

This is hardly worth mentioning except it does come up sometimes from Perl programmers.

🌐
Timothygebhard
timothygebhard.de › posts › named-groups-in-regex-in-python
Named groups for regex in Python · Timothy Gebhard
import re test_string = 'alpha=1.4 beta=2 gamma=43 delta=None' pattern = re.compile('beta=(?P<beta>\d+).*delta=(?P<delta>.+)') matches = pattern.match(test_string) if matches is not None: beta = matches.group('beta') delta = matches.group('delta')
🌐
PYnative
pynative.com › home › python › regex › python regex capturing groups
Python Regex Capturing Groups – PYnative
April 12, 2021 - Python regex capturing groups match several distinct patterns inside the same target string using group() and groups()
Find elsewhere
🌐
LearnByExample
learnbyexample.github.io › py_regular_expressions › groupings-and-backreferences.html
Groupings and backreferences - Understanding Python re(gex)?
Since \g&LTN> syntax is not available in RE definition, use formats like hexadecimal escapes to avoid ambiguity between normal digit characters and backreferences. >>> s = 'abcdefghijklmna1d' # even though there's only one capture group, \11 will give an error >>> re.sub(r'(.).*\11', 'X', s) re.PatternError: invalid group reference 11 at position 6 # use escapes for the digit portion to distinguish from the backreference >>> re.sub(r'(.).*\1\x31', 'X', s) 'Xd' # there are 12 capture groups here, so no error # but requirement is \1 as backreference and 1 as normal digit >>> re.sub(r'(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.).*\11', 'X', s) 'abcdefghijklmna1d' # use escapes again >>> re.sub(r'(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.).*\1\x31', 'X', s) 'Xd'
🌐
W3Schools
w3schools.com › python › python_regex.asp
Python RegEx
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
🌐
Reddit
reddit.com › r/learnpython › (regex | regular expression) match.group(1) = 'none' due to using appended patterns
r/learnpython on Reddit: (Regex | Regular expression) match.group(1) = 'None' due to using appended patterns
December 19, 2024 -

Hi there,

I am using regex to get 'pack size' (how a product is packaged) out of product descriptions. So 'Apple 1x300g' and taking out '1x300g'.

The issue is that there are lots of different variants a pack size can be, so I have been using the '|' between the regex expressions. However, when doing this it doesn't allow the match.group(n), where n >1 to work.

Quick example:

description = 'apple 1x300g'

UoM = r'(g|kg|ml) #Meaning Unit's of Measure
all_patterns = (

r'(\d+)\s*x\s*+(\d+)' + UoM + r'|'

r'(\d+)\s*' + UoM +r'\s*x(\d+)'

)

match = re.search(all_patterns, description)

However, match.group(0) will give '1x300g' and match.group(1) will be 'none' as all_patterns is just one big or. I am wanting it to be '1' and '300g'.

Is there a simple fix, other than looping through the patterns?

I am new to regex so appreciate any help.

PL :)

Top answer
1 of 3
3
I'm not sure if reddit messed up your code or something, but there seems some missing escapes in the regex (e.g. d+ rather than \d+). Secondly, there's something strange, 1x300g does not match the pattern you provided, since it requires at least one whitespace character after the 'x'. The groups when there are alternatives are not independent. For example, in the regex a(\d)|b(\d) there are two groups, group(1) would be the digit after an 'a', and group(2) would be the digit after a 'b'. group(0) is always the entire match. e.g. >>> re.search("a(\d)|b(\d)", "a1").groups() ('1', None) >>> re.search("a(\d)|b(\d)", "b1").groups() (None, '1') The built-in 're' module does not support overlapping groups, but you can name them: >>> re.search("a(?P\d)|b(?P\d)", "a1").groupdict() {'adigit': '1', 'bdigit': None} >>> re.search("a(?P\d)|b(?P\d)", "b1").groupdict() {'adigit': None, 'bdigit': '1'} So you can first figure out whether you are in the 'a' or 'b' case, then access the correct group. The third-party 'regex' package does support overlapping groups, which means you can make code a bit more robust: >>> import regex >>> regex.search("a(?P\d)|b(?P\d)", "a1").groupdict() {'digit': '1'} >>> regex.search("a(?P\d)|b(?P\d)", "b1").groupdict() {'digit': '1'}
2 of 3
2
Is there a simple fix, other than looping through the patterns? I recommend doing this instead. It keeps each regex simple. Make a function for each alternative, and attempt to apply each of them. If you run into performance problems, break up the text line-by-line so that each search is relatively small.
🌐
Built In
builtin.com › articles › python-re-match
Python re.match() and re.sub() Explained | Built In
Can use captured groups for dynamic replacements or even a function. re.match(): Checks for a match at the beginning of a string. Useful for validation or checking the start of a string. re.search(): Searches for a pattern anywhere in the string, not limited to the start. These examples should give you a more comprehensive understanding of how regex works in Python!
🌐
Note.nkmk.me
note.nkmk.me › home › python
How to Use Regex Match Objects in Python | note.nkmk.me
May 18, 2023 - When using grouping, the group() method allows you to access the string of any group by specifying a number as an argument. If the argument is omitted or set to 0, it returns the entire match.
🌐
Google
developers.google.com › google for education › python › python regular expressions
Python Regular Expressions | Python Education | Google for Developers
The code match = re.search(pat, str) stores the search result in a variable named "match". Then the if-statement tests the match -- if true the search succeeded and match.group() is the matching text (e.g. 'word:cat'). Otherwise if the match is false (None to be more specific), then the search did not succeed, and there is no matching text. The 'r' at the start of the pattern string designates a python "raw" string which passes through backslashes without change which is very handy for regular expressions (Java needs this feature badly!).
🌐
Python
python.org › about
About Python™ | Python.org
Python can be easy to pick up whether you're a first time programmer or you're experienced with other languages.
🌐
Its Linux FOSS
itslinuxfoss.com › home › python › python regex capturing groups
Python Regex Capturing Groups – Its Linux FOSS
March 22, 2023 - The “output.group()” function is used to display the first and second capture groups separately. ... The multiple patterns have been captured from the given string. The following code is utilized to capture the multiple regex patterns from the given string: ... import re string_value= "PYTHON guide PROVIDED by ITSLINUXFOSS" output= re.compile (r"(\b[A-Z]+\b)") for m in output.finditer(string_value): print(m.group())
🌐
Snowflake Community
community.snowflake.com › s
Snowflake Community
1 month ago - Join our community of data professionals to learn, connect, share and innovate together
🌐
BT Group
jobs.bt.com
BT Group Careers
We’re transforming the way we work – and offering more opportunities than ever across BT Group. Our state-of-the-art workspaces offer new ways to connect, create and collaborate.
🌐
Medium
medium.com › @garybao › mastering-regular-expression-matching-with-re-match-and-group-in-python-2b5c0cd860a6
Mastering Regular Expression Matching with re.match and .group() in Python | by Gary Bao | Medium
February 13, 2024 - It returns a match object if the pattern is found, or None otherwise. Here’s the basic syntax of re.match(): ... Once a match is found using re.match(), we can use the .group() method to extract specific parts of the matched text.
🌐
GitHub
github.com › getsops › sops
GitHub - getsops/sops: Simple and flexible tool for managing secrets · GitHub
SOPS uses Shamir's Secret Sharing to split the data key such that each key group has a fragment, each key in the key group can decrypt that fragment, and a configurable number of fragments (threshold) are needed to decrypt and piece together the complete data key. When decrypting a file using multiple key groups, SOPS goes through key groups in order, and in each group, tries to recover the fragment of the data key using a master key from that group.
Author   getsops
🌐
Plain English
python.plainenglish.io › capturing-groups-in-python-regex-real-world-example-7655e6c645d2
Capturing Groups in Python Regex : Real-World Example | by Prathik C | Python in Plain English
July 22, 2025 - Capturing groups take regex from a blunt instrument to a scalpel. With them, you can extract and manipulate text at a granular level. Start small, but aim for complex, structured parsing problems — because that’s where the real value of regex kicks in. ... New Python content every day.