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
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.

🌐
Python documentation
docs.python.org › 3 › howto › regex.html
Regular Expression HOWTO — Python 3.14.3 documentation
From: author@example.com User-Agent: Thunderbird 1.5.0.9 (X11/20061227) MIME-Version: 1.0 To: editor@example.com · This can be handled by writing a regular expression which matches an entire header line, and has one group which matches the header name, and another group which matches the header’s value.
🌐
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()
🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations — Python 3.14.3 ...
For example, the expressions (a)b, ((a)(b)), and ((ab)) will have lastindex == 1 if applied to the string 'ab', while the expression (a)(b) will have lastindex == 2, if applied to the same string.
🌐
GeeksforGeeks
geeksforgeeks.org › python › re-matchobject-group-function-in-python-regex
re.MatchObject.group() function in Python Regex - GeeksforGeeks
July 15, 2025 - Note the use of '()' the parenthesis ... above example, we have three subgroups in the match pattern. The result we get is a re.MatchObject which is stored in match_object. Note: To know more about regex patterns refer Python regex · Depending on the arguments passed the group method returns ...
🌐
Google
developers.google.com › google for education › python › python regular expressions
Python Regular Expressions | Python Education | Google for Developers
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!).
🌐
Note.nkmk.me
note.nkmk.me › home › python
How to Use Regex Match Objects in Python | note.nkmk.me
May 18, 2023 - Be careful when using * to denote zero or more repetitions, as demonstrated in the example. If you wish to treat a match with an empty string as a non-match, you can first evaluate the match object and then further evaluate the string obtained using the group() method. Python · String · Regex ·
🌐
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.
Find elsewhere
🌐
Spark By {Examples}
sparkbyexamples.com › home › python › python regex groups
Python regex groups - Spark By {Examples}
May 31, 2024 - Group 1 corresponds to the first set of parentheses, Group 2 corresponds to the second set of parentheses, and Group 3 corresponds to the third set of parentheses in the pattern. ... Named groups in Python regex allow us to assign names to specific ...
🌐
Imperial College London
python.pages.doc.ic.ac.uk › lessons › regex › 07-groups › 02-named.html
Ic
This is done with (?P<name> ). Note that name must be a valid Python identifier. The names make the groups more semantically meaningful, rather than having to refer to them by a number. As usual, try out the examples yourself and make sure you understand what each line is doing (should be self-explanatory). Consult the documentation if you have doubts. >>> pattern = "Name: (?P<name>[A-Za-z ]+); Phone: (?P<phone>\d+)" >>> string = "Name: Josiah Wang; Phone: 012345678" >>> match = re.match(pattern, string) >>> print(match) <re.Match object; span=(0, 35), match='Name: Josiah Wang; Phone: 012345678'> >>> match.group("name") 'Josiah Wang' >>> match.group("phone") '012345678' >>> match.group(1) 'Josiah Wang' >>> match.group(2) '012345678' >>> match.groupdict() {'name': 'Josiah Wang', 'phone': '012345678'}
🌐
Timothygebhard
timothygebhard.de › posts › named-groups-in-regex-in-python
Named groups for regex in Python · Timothy Gebhard
So without further ado, here’s ...>\d+).*delta=(?P<delta>.+)') matches = pattern.match(test_string) if matches is not None: beta = matches.group('beta') delta = matches.group('delta')...
🌐
Python Tutorial
pythontutorial.net › home › python regex › python regex capturing group
Python Regex Capturing Groups
February 18, 2022 - To get all the named subgroups of a match, you use the groupdict() method of the Match object. For example: import re s = 'news/100' pattern = '(?P<resource>\w+)/(?P<id>\d+)' matches = re.finditer(pattern, s) for match in matches: print(match.groupdict())Code language: Python (python)
🌐
LearnByExample
learnbyexample.github.io › py_regular_expressions › groupings-and-backreferences.html
Groupings and backreferences - Understanding Python re(gex)?
It may be obvious, but it should ... capture group. For example, if (\d[a-f]) matches 3b, then backreferencing will give 3b and not any other valid match of RE like 8f, 0a etc. This is akin to how variables behave in programming, only the result ...
🌐
LabEx
labex.io › tutorials › python-how-to-use-regex-capture-groups-in-python-420906
How to use regex capture groups in Python | LabEx
Capture groups are a powerful feature in regular expressions that allow you to extract and group specific parts of a matched pattern. In Python, they are defined using parentheses () within a regex pattern. Let's start by creating a Python script to demonstrate basic capture group usage. Open the integrated terminal in the WebIDE and navigate to the project directory if you are not already there. ... Create a new file named basic_capture.py using the touch command. ... import re text = "Contact email: john.doe@example.com" pattern = r"(\w+)\.(\w+)@(\w+)\.(\w+)" match = re.search(pattern, text) if match: username = match.group(1) lastname = match.group(2) domain = match.group(3) tld = match.group(4) print(f"Username: {username}") print(f"Lastname: {lastname}") print(f"Domain: {domain}") print(f"TLD: {tld}") else: print("No match found.")
🌐
TutorialsPoint
tutorialspoint.com › how-do-we-use-python-regular-expression-named-groups
How do we use Python Regular Expression named groups?
Following is the Python example, which demonstrates how to match a particular pattern in a string using groups - import re input_string = "Tutorials Point began as a single HTML tutorial and has since expanded to offer a wide range of online courses and tutorials. It was established on 2014-06-12." regexp = r"(\d{4})-(\d{2})-(\d{2})" match = re.search(regexp, input_string) if match: print("Found date in the given text:", match.group(0)) print("Year:", match.group(1)) print("Month:", match.group(2)) print("Day:", match.group(3))
🌐
Finxter
blog.finxter.com › home › learn python blog › python re groups
Python Re Groups - Be on the Right Side of Change
May 5, 2023 - ... Like you use parentheses to ... expressions. An example regex that does this is 'a(b|c)'. The whole content enclosed in the opening and closing parentheses is called matching group (or capture group)....
🌐
ZetCode
zetcode.com › python › regex-match-group-method
Python Match.group - Mastering Regular Expression Groups
Each group matches a specific number of digits. ... We access each group by its position. Group 1 contains the year, group 2 the month, and group 3 the day. Named groups make patterns more readable and maintainable. ... #!/usr/bin/python import re text = "Temperature: 23.5°C" pattern = ...
🌐
Safjan
safjan.com › home › note › python regex named groups
Python Regex Named Groups
July 11, 2023 - In the above example, the regular expression pattern matches a date string in the format 'yyyy-mm-dd', and each part of the date is captured using named groups. The groupdict() method returns a dictionary with keys 'year', 'month', and 'day', ...
🌐
InfoWorld
infoworld.com › home › software development › programming languages › python
Python regex: How to use Python regular expressions | InfoWorld
February 24, 2021 - Normally, capture groups are referred to by an index, but you can assign names to them if you want. match.groupdict() lets you refer to those capture groups by name, as you would the contents of any other dictionary. When you create a Python regex, you can pass a number of options that control ...
🌐
LearnByExample
learnbyexample.github.io › py_regular_expressions › working-with-matched-portions.html
Working with matched portions - Understanding Python re(gex)?
If part of the pattern is outside a capture group, the text thus matched won't be in the output. If a capture group didn't participate, it will be represented by None in the output list. # here 4?2 is outside the capture group, so that portion won't be in the output >>> re.split(r'(1*)4?2', '31111111111251111426') ['3', '1111111111', '5', '1111', '6'] # multiple capture groups example # note that the portion matched by b+ isn't present in the output >>> re.split(r'(a+)b+(c+)', '3.14aabccc42') ['3.14', 'aa', 'ccc', '42'] # here (4)?