You need the first captured group:

a.group(1)
b.group(1)
...

without any captured group specification as argument to group(), it will show the full match, like what you're getting now.

Here's an example:

In [8]: string_one = 'file_record_transcript.pdf'

In [9]: re.search(r'^(file.*)\.pdf$', string_one).group()
Out[9]: 'file_record_transcript.pdf'

In [10]: re.search(r'^(file.*)\.pdf$', string_one).group(1)
Out[10]: 'file_record_transcript'
Answer from heemayl on Stack Overflow
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ library โ€บ re.html
re โ€” Regular expression operations
4 days ago - The regex matching flags. This is a combination of the flags given to compile(), any (?...) inline flags in the pattern, and implicit flags such as UNICODE if the pattern is a Unicode string. ... The number of capturing groups in the pattern.
Discussions

(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
regex - Match groups in Python - Stack Overflow
Is there a way in Python to access match groups without explicitly creating a match object (or another way to beautify the example below)? Here is an example to clarify my motivation for the quest... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Python Conditional Regex to Print Decimal Number
re.findall will return the result captured in your capture group. Just use a non-capture group instead >>> (?: More on reddit.com
๐ŸŒ r/regex
11
3
February 18, 2021
๐ŸŒ
Python documentation
docs.python.org โ€บ 3 โ€บ howto โ€บ regex.html
Regular Expression HOWTO โ€” Python 3.14.3 documentation
(The first edition covered Pythonโ€™s now-removed regex module, which wonโ€™t help you much.) Consider checking it out from your library. Regular Expression HOWTO ยท Introduction ยท Simple Patterns ยท Matching Characters ยท Repeating Things ยท Using Regular Expressions ยท Compiling Regular Expressions ยท The Backslash Plague ยท Performing Matches ยท Module-Level Functions ยท Compilation Flags ยท More Pattern Power ยท More Metacharacters ยท Grouping ยท
๐ŸŒ
Python
python.org โ€บ downloads โ€บ release โ€บ python-3119
Python Release Python 3.11.9 | Python.org
gh-34627 -- Atomic grouping ((?>...)) and possessive quantifiers (*+, ++, ?+, {m,n}+) are now supported in regular expressions.
๐ŸŒ
Shtetl-Optimized
scottaaronson.blog
On reducing the cost of breaking RSA-2048 to 100,000 physical qubits
So, a group based in Sydney, Australia has put out a preprint with a new estimate of the resource requirements for Shor's algorithm, claiming that if you use LDPC codes rather than the surface code, you should be able to break RSA-2048 with ...
๐ŸŒ
Timothygebhard
timothygebhard.de โ€บ posts โ€บ named-groups-in-regex-in-python
Named groups for regex in Python ยท Timothy Gebhard
July 23, 2022 - I figured that maybe it is about time I just write down the correct syntax myself once, so that either my brain will now remember it, or that I at least know where to look it so. So without further ado, hereโ€™s the example code for named group using Pythonโ€™s re module:
Find elsewhere
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ re-matchobject-group-function-in-python-regex
re.MatchObject.group() function in Python Regex - GeeksforGeeks
July 15, 2025 - re.MatchObject.group() method returns the complete matched subgroup by default or a tuple of matched subgroups depending on the number of arguments
๐ŸŒ
Python
python.org
Welcome to Python.org
Calculations are simple with Python, and expression syntax is straightforward: the operators +, -, * and / work as expected; parentheses () can be used for grouping.
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ python_regex.asp
Python RegEx
.span() returns a tuple containing the start-, and end positions of the match. .string returns the string passed into the function .group() returns the part of the string where there was a match
๐ŸŒ
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()
๐ŸŒ
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 of an expression stays after variable assignment, not the expression itself. The regex module supports ...
๐ŸŒ
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.
๐ŸŒ
Medium
medium.com โ€บ @MynaviTechTusVietnam โ€บ regex-for-dummies-part-4-capturing-groups-and-backreferences-50c338a3b6f6
Regex For Dummies. Part 4: Capturing Groups and Backreferences | by Mynavi TechTus Vietnam | Medium
October 17, 2023 - Named capturing groups allow you to assign names to your capturing groups, making it easier to reference and work with specific matched portions of text. Instead of referring to capturing groups by their numerical indices, you can use descriptive names, which enhances the readability and maintainability of your regex patterns.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ accessing a "symbolic group name" in python regex
r/learnpython on Reddit: Accessing a "symbolic group name" in Python regex
November 28, 2022 -

Hello all,

I'm trying to understand how to access a "symbolic group name" within regex groups.

https://docs.python.org/3.10/library/re.html?highlight=re#regular-expression-syntax

The documentation states:

"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 each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named.

Named groups can be referenced in three contexts. If the pattern is (?P<quote>['"]).*?(?P=quote) (i.e. matching a string quoted with either single or double quotes):"

I would have expected to do something like this:

import re

text_string = 'This is a nice string: we should use it some time\r\nThis is NOT a nice string: we should NEVER use it\r\n'

found = re.findall(r'(?P<name>.*?): (?P<value>.*?)\r\n', text_string)

print(f'Data Content:\t{found[0]("value")}')

If I'm correct and you can access a symbolic group name how do you do it? The documentation is not very clear on that section.

Kind regards

๐ŸŒ
Imperial College London
python.pages.doc.ic.ac.uk โ€บ lessons โ€บ regex โ€บ 07-groups โ€บ 02-named.html
Advanced Lesson 1: Regular Expressions > Named groups
>>> 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'}
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.

๐ŸŒ
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 - However, be aware that some regex patterns may match a zero-length string (empty string ''), which is still evaluated as True. m = re.match('[0-9]*', s) print(m) # <re.Match object; span=(0, 0), match=''> print(m.group() == '') # True print(bool(m)) # True if re.match('[0-9]*', s): print('match') else: print('no match') # match
๐ŸŒ
Python Tutorial
pythontutorial.net โ€บ home โ€บ python regex โ€บ python regex non-capturing group
Python Regex Non-capturing Group
December 11, 2021 - import re s = 'Python 3.10' pattern = '\d+\.(\d+)' match = re.search(pattern, s) # show the whole match print(match.group()) # show the groups for group in match.groups(): print(group)Code language: Python (python) ... So why do you use the non-capturing group anyway? the reason for using the non-capturing group is to save memory, as the regex engine doesnโ€™t need to store the groups in the buffer.
๐ŸŒ
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.