It is easy enough to make the season group optional:

(^.*?)(?:\Ws(?:eason )?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art )?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)

using a non-capturing group ((?:...)) plus the 0 or 1 quantifier (?). I did have to make the first group non-greedy to prevent it from matching the season section of the name.

I also made the eason and art optional strings into non-capturing optional groups instead of character classes.

Result:

>>> import re
>>> p=re.compile(r'(^.*?)(?:\Ws(?:eason )?(\d{1,2}|[ivxlcdm]{1,5}))?\Wp(?:art )?(\d{1,2}|[ivxlcdm]{1,5})\W(.*$)', re.I)
>>> p.search('miniseries.season 1.part 5.720p.avi').groups()
('miniseries', '1', '5', '720p.avi')
>>> p.search('miniseries.part 5.720p.avi').groups()
('miniseries', None, '5', '720p.avi')
>>> p.search('miniseries.part VII.720p.avi').groups()
('miniseries', None, 'VII', '720p.avi')
Answer from Martijn Pieters on Stack Overflow
🌐
Reddit
reddit.com › r/regex › capture one group with an optional group inside
r/regex on Reddit: Capture one group with an optional group inside
February 3, 2021 -

I need to capture a group which contains a partial optional part inside, but I can't manage to build it.

Example: iphone or iphone11

I need to capture iphone (if it's only iPhone) or iphone11 if it has the 11 together. This is just an example, it isn't necessarily numbers.

Example 2: abcd or abcdef

I want to capture abcd or abcdef.

I was trying by using this:

(iphone(11)?) OR (abcd(ef)?)

But it obviously gives me 2 results if the second capturing group exists. And I need it as 1 result only.

It's more complex that simply putting simple alternatives like this:

(iphone|iphone11)

PCRE

Edit: clarifying

Discussions

Using regex for an optional string
Great stuff here! I’m fairly decent with basic Regex, but where I struggle with is with an example like below === Submission 1 Name: Bryan Email: test@abc.com Phone: 012345 === Submission 2 Name:Bryan2 Phone: 0141231 Normally what I would have done is used a Regex pattern of Name:(.)\nEm... More on community.make.com
🌐 community.make.com
1
0
April 19, 2022
How can I make an optional named group with Regex Columnizer?
I want to catch strings in named groups. the second string is optional. If this optional string is missing my regex code not working. (? string1) (? string2)? (? More on github.com
🌐 github.com
1
January 1, 2019
Problem with optional group captured by another group
(\w+)\s*:\s*([\w[], | ^\w]+)(, optional)? The problem is that the second group is in no way restricted from consuming the text in the third group because the + quantifier is greedy. Instead: "(\w+)\s*:\s*([\w\[\], \| \^\w]+?)(?:(, optional)|$)"gm Consume as few characters as possible until reaching the optional group or the end of the line, whichever occurs first. https://regex101.com/r/wdDXQ1/1 EDIT: On second thought, it may work better to enforce that the optional group occurs at the end of the line, or not at all. "(\w+)\s*:\s*([\w\[\], \| \^\w]+?)(?:(, optional)?)$"gm https://regex101.com/r/q7HBa2/1 More on reddit.com
🌐 r/regex
2
3
August 9, 2024
regex - Optional named groups Python re - Stack Overflow
In the Django urls I need an optional named group. This conf without arguments raised an 404 exception: r'^list_cv/(?P [\d]+)?/$' How to make optional named group? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python documentation
docs.python.org › 3 › howto › regex.html
Regular Expression HOWTO — Python 3.14.3 documentation
Author, A.M. Kuchling ,. Abstract: This document is an introductory tutorial to using regular expressions in Python with the re module. It provides a gentler introduction than th...
🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations
4 days ago - Return a tuple containing all the subgroups of the match, from 1 up to however many groups are in the pattern. The default argument is used for groups that did not participate in the match; it defaults to None.
🌐
Python Pool
pythonpool.com › home › blog › the secret guide to regex optional group
The Secret Guide To Regex Optional Group - Python Pool
January 22, 2022 - It is good if we find it or not. To do that, we used “?” after both the parentheses, which tells that the preceding character is not compulsory to match. Hence, it returns all the numbers by matching them. In this way, we can use optional groups while matching patterns using regex.
🌐
GitHub
github.com › zarunbal › LogExpert › issues › 86
How can I make an optional named group with Regex ...
January 1, 2019 - I want to catch strings in named groups. the second string is optional. If this optional string is missing my regex code not working. (? string1) (? string2)? (?
Published   Jan 01, 2019
Find elsewhere
🌐
Reddit
reddit.com › r/regex › problem with optional group captured by another group
r/regex on Reddit: Problem with optional group captured by another group
August 9, 2024 -

Hello, I'm trying to parse python docstrings (numpy format), which consists of 3 capture groups, but the last group (which is optional) ends up in the 2nd group. Can you help me get it to correctly assign ", optional" to the third group, if it exists in the string? (I don't actually need the third group, but I need the second group to not contain the ", optional" part)

You can see the issue in this picture - I would like ", optional" to be in a separate group.

Regex:
(\w+)\s*:\s*([\w\[\], \| \^\w]+)(, optional)?

Test cases:

a: int

a: Dict[str, Any]

a: str | any

a: int, optional

a: str | any, optional

🌐
MDN Web Docs
developer.mozilla.org › en-US › docs › Web › JavaScript › Reference › Regular_expressions › Non-capturing_group
Non-capturing group: (?:...) - JavaScript | MDN
July 8, 2025 - ... A pattern consisting of anything you may use in a regex literal, including a disjunction. In the following example, we test if a file path ends with styles.css or styles.[a hex hash].css. Because the entire \.[\da-f]+ part is optional, in order to apply the ?
🌐
Python Tutorial
pythontutorial.net › home › python regex › python regex non-capturing group
Python Regex Non-capturing Group
December 11, 2021 - Suppose you don’t want to capture the digits before the literal character (.), you can use a non-capturing group like this: 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)
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-regex-replace-captured-groups
Python Regex: Replace Captured Groups - GeeksforGeeks
July 23, 2025 - You can use backreferences to include captured groups in the replacement. `string`: The original string where the replacement is performed. `count`: The maximum number of replacements. Default is `0`, which means replace all occurrences. `flags`: Optional flags to modify the regex behavior. Python ...
🌐
regex101
regex101.com › library › 5ocoEo
regex101: Optional Named Groups
Search, filter and view user submitted regular expressions in the regex library. Over 20,000 entries, and counting!
🌐
Finxter
blog.finxter.com › home › learn python blog › python regex named groups
Python Regex Named Groups - Be on the Right Side of Change
October 27, 2022 - Use the named group syntax (?P<name>...) with your name and append a question mark quantifier ? after it to make the whole named group match either zero or one time, i.e., make it optional using (?P<name>...)?. For example, (?P<age>.*)?
Top answer
1 of 2
2

If you want to keep the 2 capturing groups and you want to match a range from 1-24 followed by hour and optionally a space and 30 minutes, you might shorten the pattern to:

(\d{4})(?:.* ((?:[1-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?))?

In parts

  • (\d{4}) Capture group 1 Match 4 digits (You might prepend a word boundary \b)
  • (?: Non capturing group
    • .* Match any char 0+ times followed by a space (Or use .*\b)
    • ( Capture group 2
      • (?:[1-9]|1[0-9]|2[0-4]) hour Match a range 1-24 followed by hour
      • (?: 30 minutes)? Optionally match 30 minutes
    • ) Close group 2
  • )? Close on capturing group and make it optional

Regex demo

2 of 2
1

I didn't change your pattern a lot because you didn't explain what you want to extract exactly.

When you make second group optional everything will be consumed by .* because it's greedy, so you need to fix this first .*?.

now the second group should be also put in a non capturing group to match either the text ends with something like for 1 hour or end of line \n.

check this:

import re

text = """
(1) Pay for zone 1234 for 1 hour
(2) Pay for zone 4567
(3) Pay for zone 1234 for 1 hour 30 minutes
"""

RE = r'(\d{4}).*?(?:(30 minutes|1 hour(?: 30 minutes)?|(?:[2-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?)|\n)'
# same thing using compile with flags MULTILINE
# RE = re.compile(r'(\d{4}).*?(?:(30 minutes|1 hour(?: 30 minutes)?|(?:[2-9]|1[0-9]|2[0-4]) hour(?: 30 minutes)?)|$)', flags=re.MULTILINE)

print(re.findall(RE, text))

OUTPUT:

  [('1234', '1 hour'), ('4567', ''), ('1234', '1 hour 30 minutes')]
🌐
Medium
mipsmonsta.medium.com › 10-things-to-know-about-python-regex-as-an-advanced-user-5d0b912b24a8
10 Things to Know About Python Regex as An Advanced User | by Mipsmonsta | Medium
October 6, 2020 - Consider credit card numbers, which are commonly segregated by “-” characters for every group of four digits. However, those filled up on websites could be transmitted as 16 digits string without the “-”. Or sometimes, there are lesser “-”s than expected. So how can we detect valid credit card numbers. Turns out we can use backreference of optional capture groups to match valid credit numbers, with or without “-”s.
🌐
Stack Overflow
stackoverflow.com › questions › 47688358 › python-regex-how-to-make-a-group-of-words-character-optional
Python regex: How to make a group of words/character optional? - Stack Overflow
Match a word character one or more times with an optional hyphen \w+\-? Or | A hyphen with one or more word characters \-\w+ Close the non capturing group ) End of the string $ Share · Improve this answer · Follow · answered Dec 7, 2017 at 7:31 · The fourth birdThe fourth bird · 165k1616 gold badges6060 silver badges7575 bronze badges · Add a comment · Start asking to get answers · Find the answer to your question by asking. Ask question · Explore related questions · python · regex ·
🌐
Splunk Community
community.splunk.com › t5 › Splunk-Search › How-do-you-make-a-regex-that-skips-an-optional-word › m-p › 436799
How do you make a regex that skips an optional wor... - Splunk Community
September 29, 2020 - The '?' after the '(administratively )' capture group, basically tells the regex that the previous group/character is optional.