I think you're misunderstanding the concept of a "non-capturing group". The text matched by a non-capturing group still becomes part of the overall regex match.

Both the regex (?:aaa)(_bbb) and the regex (aaa)(_bbb) return aaa_bbb as the overall match. The difference is that the first regex has one capturing group which returns _bbb as its match, while the second regex has two capturing groups that return aaa and _bbb as their respective matches. In your Python code, to get _bbb, you'd need to use group(1) with the first regex, and group(2) with the second regex.

The main benefit of non-capturing groups is that you can add them to a regex without upsetting the numbering of the capturing groups in the regex. They also offer (slightly) better performance as the regex engine doesn't have to keep track of the text matched by non-capturing groups.

If you really want to exclude aaa from the overall regex match then you need to use lookaround. In this case, positive lookbehind does the trick: (?<=aaa)_bbb. With this regex, group() returns _bbb in Python. No capturing groups needed.

My recommendation is that if you have the ability to use capturing groups to get part of the regex match, use that method instead of lookaround.

Answer from Jan Goyvaerts on Stack Overflow
Top answer
1 of 7
158

I think you're misunderstanding the concept of a "non-capturing group". The text matched by a non-capturing group still becomes part of the overall regex match.

Both the regex (?:aaa)(_bbb) and the regex (aaa)(_bbb) return aaa_bbb as the overall match. The difference is that the first regex has one capturing group which returns _bbb as its match, while the second regex has two capturing groups that return aaa and _bbb as their respective matches. In your Python code, to get _bbb, you'd need to use group(1) with the first regex, and group(2) with the second regex.

The main benefit of non-capturing groups is that you can add them to a regex without upsetting the numbering of the capturing groups in the regex. They also offer (slightly) better performance as the regex engine doesn't have to keep track of the text matched by non-capturing groups.

If you really want to exclude aaa from the overall regex match then you need to use lookaround. In this case, positive lookbehind does the trick: (?<=aaa)_bbb. With this regex, group() returns _bbb in Python. No capturing groups needed.

My recommendation is that if you have the ability to use capturing groups to get part of the regex match, use that method instead of lookaround.

2 of 7
65

group() and group(0) will return the entire match. Subsequent groups are actual capture groups.

>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(0))
aaa_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(1))
_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(2))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: no such group

If you want the same behavior than group():

" ".join(re.match(r"(?:aaa)(_bbb)", string1).groups())

🌐
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 ... (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....
Discussions

Should I use non-capturing groups if I don't care whether they capture?
Well, there is some overhead required to store captured groups, so there would always be a performance boost if one uses non-capturing groups, though depending on the pattern it's usually a boost you won't really notice that well, if at all. I think the main reason for me to use non-capturing structure is to avoid unexpected results on some programming languages, e.g. Python's re.findall. let me give an example. If you are using alternation constructs in a much larger validation, you'd need paranthesis around the expression. This can be done using capture groups but better would be a non capturing group to prevent re.findall to return the found alternative instead of the larger substring the alternative had been part of. So IMO, unless you'd use the capturing group for backreference or a replacement function I think it's actually still wise to use non-capturing group. Maybe others think differently. More on reddit.com
🌐 r/regex
6
12
January 10, 2021
Regex capture / non-capture groups best practice
I've been playing with regex, reading forums and trying out various code on regex101. In Pi-hole I currently have the following blacklist entry (just one example of many) ^(meetings|hangouts|suggestqueries).*google(apis)?\.com$ I hadn't appreciated until now that this creates two capture groups. More on discourse.pi-hole.net
🌐 discourse.pi-hole.net
1
0
February 18, 2023
Can someone explain what are non-capture groups?
By default, when you use parenthesis, regex remembers (captures) what was matched. You can then reference what was matched later in your substitution or even within the original regular expression. The downside is that it also has more overhead because it's remembering whatever was matched. If you don't need to have the match remembered, you can just change your regular [capture] group to a non-capture group by adding in the ?: after the opening parenthesis. As far as the regex engine is concerned, there's no real difference for applying the expression to your string - other than you will no longer be able to access what was matched inside of the non-capture group. More on reddit.com
🌐 r/regex
6
10
February 8, 2021
I'm sooo confused (non capturing groups)
I'm not familiar with that particular site, but I hope they cover some things you can do with groups, like repetitions (quantifiers). The main point of making it a non-capturing group is to group, but not capture (thanks, captain obvious). This can help with using less memory (non-capturing means that once it matches the regex engine can forget what it actually matched. Or simply making it clear what parts of the regex are going to be used later, making your regex easier to read for someone later. For example: ^(?:[^,]*,){14}([^,]*),(?:[^,]*),([^,]*) https://regex101.com/r/LIYAXA/1 I would say that makes it clear that I am not interested in the sixteenth repetition or the 14th in front, just needed to match those to get to the part I did want to capture. More on reddit.com
🌐 r/regex
3
3
September 6, 2022
🌐
Python documentation
docs.python.org › 3 › howto › regex.html
Regular Expression HOWTO — Python 3.14.3 documentation
Except for the fact that you can’t retrieve the contents of what the group matched, a non-capturing group behaves exactly the same as a capturing group; you can put anything inside it, repeat it with a repetition metacharacter such as *, and nest it within other groups (capturing or non-capturing).
🌐
Reddit
reddit.com › r/regex › should i use non-capturing groups if i don't care whether they capture?
r/regex on Reddit: Should I use non-capturing groups if I don't care whether they capture?
January 10, 2021 -

Let's say I'm just doing string validation and I don't care whether my groups capture or not. Is it advisable to use regular groups so that my expression has fewer characters and it's easier for people to understand? I like to use non-capturing groups by default because it feels polite to give the engine less work, but I don't think there's any appreciable impact on performance. Sorry if this is on a list of best practices, I couldn't find one.

🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations
4 days ago - A non-capturing version of regular parentheses. Matches whatever regular expression is inside the parentheses, but the substring matched by the group cannot be retrieved after performing a match or referenced later in the pattern.
🌐
Medium
medium.com › @yeukhon › non-capturing-group-in-pythons-regular-expression-75c4a828a9eb
Non-capturing group in Python’s regular expression | by Facing Security | Medium
August 29, 2014 - If one or more groups are present ... are included in the result unless they touch the beginning of another match. The (?: stuff gones inside) syntax is a non-capturing group....
Find elsewhere
🌐
Educative
educative.io › answers › what-is-a-non-capturing-group-in-regular-expressions
What is a non-capturing group in regular expressions?
When we call match on the phone ... expression, regexWithNonCapturingGroup, uses a non-capturing group to match the first three digits of the phone number, but does not capture them....
🌐
Reddit
reddit.com › r/regex › can someone explain what are non-capture groups?
r/regex on Reddit: Can someone explain what are non-capture groups?
February 8, 2021 -

Hi everyone!

I'm struggling to understand what are non-capturing groups.

My take and if I understood correctly:

  • when you group, you're applying precedence in terms of evaluation, like normal parenthesis would work in a math expression.

  • a normal group it creates some sort of indexing that the regex engine can use for other checks later on if it has advanced stuff like tagging or recursion.

  • when you use ?: - non-capturing group - you're also grouping as well but it doesn't do any indexing.

Is this correct?

Would there any difference between simple stuff like (^$)|(^(No|Yes)$) to (?:^$)|(?:^(?:No|Yes)$) ?

Thank you in advance.

🌐
LearnByExample
learnbyexample.github.io › py_regular_expressions › groupings-and-backreferences.html
Groupings and backreferences - Understanding Python re(gex)?
Use a capture group around the grouping and quantifier together to get the entire matching portion. In such cases, the inner grouping is an ideal candidate to be specified as non-capturing.
🌐
Reddit
reddit.com › r/regex › i'm sooo confused (non capturing groups)
r/regex on Reddit: I'm sooo confused (non capturing groups)
September 6, 2022 -

So I'm doing the tutorials slowly moving through it here: https://regexlearn.com/learn/regex101 - and... why in the heck would he want to "exclude" - is that the right word - or do a non-capture group - to select all those haha characters? Like what's the point of the question mark when

(ha)-\1,(haa)-\2

Will achieve the same thing - I'm confused as to why it even needs to exist in the first place.

Thank you!

🌐
Rexegg
rexegg.com › regex-disambiguation.php
Advanced Regex Tutorial—Regex Syntax
The non-capture group (?:({)|") matches the opening delimiter, capturing it to Group 1 if it is a curly brace. After matching the digits, (?(1)}|") checks whether Group 1 was set. If so, we match a closing curly brace. If not, we match a double quote. Lookaround in Conditions In (?(A)B), the ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-regex-replace-captured-groups
Python Regex: Replace Captured Groups - GeeksforGeeks
July 23, 2025 - In such cases, we can use non-capturing groups, denoted by (?:...). ... 3. Named Capturing Groups: These groups are captured by a name rather than a numerical index, making the regex more readable.
🌐
TutorialsPoint
tutorialspoint.com › non-capturing-groups-java-regular-expressions
Non capturing groups Java regular expressions:
February 21, 2020 - Using capturing groups you can treat multiple characters as a single unit. You just need to place the characters to be grouped inside a set of parentheses. For example − (.*)(\\d+)(.*) If y
🌐
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 - To create a non-capturing group, you use a question mark and a colon right after the opening parenthesis. ... For instance, in the example “extracting the day, month, and year from birthday dates” above, if we don’t want to capture the ...
🌐
RegExr
regexr.com
RegExr: Learn, Build, & Test RegEx
RegExr is an online tool to learn, build, & test Regular Expressions (RegEx / RegExp).
🌐
Regular-Expressions.info
regular-expressions.info › refcapture.html
Regular Expression Reference: Groups and Backreferences
| Introduction | Table of Contents | Quick Reference | Characters | Basic Features | Character Classes | Shorthands | Anchors | Word Boundaries | Quantifiers | Capturing Groups & Backreferences | Named Groups & Backreferences | Special Groups | Unicode Characters and Properties | Unicode Versions | Unicode Categories | Unicode Scripts | Unicode Blocks | Unicode Binary Properties | Unicode Property Sets | Unicode Boundaries | Mode Modifiers | Recursion & Balancing Groups | Backtracking Control Verbs |
🌐
O'Reilly
oreilly.com › library › view › java-9-regular › 9781787288706 › 0408480c-ba70-4cbe-b442-b02e624cc214.xhtml
Advantages of non-capturing groups - Java 9 Regular Expressions [Book]
July 25, 2017 - Non-capturing groups also give us the flexibility to add or remove groups from a long regular expression with multiple groups.
Author   Anubhava Srivastava
Published   2017
Pages   158