Nearby lessons
130 of 159Python - Regex Quantifiers
- Understand what Quantifiers are in Regular Expressions
- Know the meaning of the quantifiers a, a+, a*, and a?
- Match exact and ranged repetitions with a{m} and a{m,n}
- Explain why a* and a? can produce empty matches
- Recognize that quantifiers are greedy by default
Introduction to Quantifiers
In Regular Expressions, Quantifiers are used to specify the number of times a character or pattern should occur.
Consider the character:
a
Using Quantifiers, we can ask questions such as:
- Is exactly one
apresent? - Are one or more
acharacters present? - Are zero or more
acharacters present? - Is zero or one
apresent? - Are exactly a specified number of
acharacters present? - Are between a minimum and maximum number of
acharacters present?
Simple Definition:
Quantifiers specify how many times a particular character or pattern should occur.
Quantifiers Covered
The following six Quantifiers are covered in this section:
| Quantifier | Meaning |
|---|---|
a |
Exactly one a |
a+ |
At least one a |
a* |
Any number of a characters, including zero |
a? |
At most one a, meaning zero or one |
a{m} |
Exactly m number of a characters |
a{m,n} |
Minimum m and maximum n number of a characters |
Target String Used in the Demo
The document demonstrates Quantifiers using the target string:
abaabaaab
Index positions are:
Character : a b a a b a a a b
Index : 0 1 2 3 4 5 6 7 8
Notice the groups of a:
a b aa b aaa b
│ ││ │││
1 2 3
This makes the string useful for understanding how different Quantifiers behave.
Complete Demo Program
Keep the target string:
abaabaaab
and change the Regular Expression inside re.finditer():
a
a+
a*
a?
a{3}
a{2,3}
The same program can therefore be used to understand all the Quantifiers.
1. a - Exactly One a
The pattern:
a
searches for exactly one occurrence of a at a time.
It does not group consecutive a characters together.
The Regex engine searches from left to right:
a b a a b a a a b
0 1 2 3 4 5 6 7 8
↑ ↑ ↑ ↑ ↑ ↑
Every individual a is treated as a separate match. For abaabaaab, a occurs at indexes:
0, 2, 3, 5, 6, 7
| Start Index | group() |
|---|---|
| 0 | a |
| 2 | a |
| 3 | a |
| 5 | a |
| 6 | a |
| 7 | a |
2. a+ - At Least One a
The Quantifier:
a+
means:
At least one
a.
In other words:
1 or more a characters
It can match:
a
aa
aaa
aaaa
...
but it cannot match zero occurrences.
The + quantifier is greedy by default, so consecutive a characters are matched together as much as possible.
Break the target into groups:
a | b | aa | b | aaa | b
a+ requires one or more consecutive a characters. Therefore:
Index 0 → a
Index 2 → aa
Index 5 → aaa
Unlike the pattern a, consecutive a characters are grouped into one match.
3. a* - Zero or More a Characters
The Quantifier:
a*
means:
Any number of
acharacters, including zero.
It can match:
"" → zero a
a → one a
aa → two a characters
aaa → three a characters
aaaa... → more a characters
This is different from a+ because a* is also allowed to match when no a is present at the current position.
The target is:
a b a a b a a a b
0 1 2 3 4 5 6 7 8
At index 0, a matches, so the output is 0 ... a. At index 1, the character is b. Because * allows zero occurrences of a, an empty match is possible: 1 .... At index 2, the consecutive a characters are aa, so the output is 2 ... aa. At index 4, we again have b, so an empty match occurs. At index 5, aaa is matched together. At index 8, b produces another empty match. Finally, an empty match is also possible at index 9, which is the position immediately after the last character.
Why Does a* Produce Empty Matches?
The key point is:
* means zero or more
Therefore, the Regex engine does not require an a to be present.
For example, consider:
b
^
Before b, the pattern can say:
There are zero consecutive a characters here.
That is a valid match for:
a*
The matched text is an empty string:
""
Therefore group() prints nothing after the dots:
1 ...
This does not mean that b matched a*. It means an empty string of zero a characters matched at that position.
The string abaabaaab contains 9 characters with indexes:
0 to 8
But a Regular Expression can also match an empty string at the position immediately after the final character:
a b a a b a a a b |
0 1 2 3 4 5 6 7 8 9
↑
End position
Because a* accepts zero a characters, it can produce:
9 ...
4. a? - At Most One a
The Quantifier:
a?
means:
At most one
a.
That means:
zero a
OR
one a
It cannot consume two or more a characters in a single match.
The question mark permits 0 or 1 occurrence. Therefore, every a is matched individually. At positions containing b, zero occurrences are valid, so empty matches occur:
Index 0 → a
Index 1 → empty
Index 2 → a
Index 3 → a
Index 4 → empty
Index 5 → a
Index 6 → a
Index 7 → a
Index 8 → empty
Index 9 → empty
Unlike a*, a? does not combine aa or aaa into one match because it allows at most one a per match.
a* vs a?
| Pattern | Meaning | Can Match Empty? | Maximum Number in One Match |
|---|---|---|---|
a* |
Zero or more | Yes | No fixed maximum |
a? |
Zero or one | Yes | 1 |
For example, for:
aaa
a* can match:
aaa
whereas a? matches one a at a time.
5. a{m} - Exactly m Occurrences
The Quantifier:
a{m}
means:
Exactly
mnumber ofacharacters.
For example:
a{3}
means:
Exactly three consecutive a characters
It matches:
aaa
The target contains groups:
a | aa | aaa
The pattern a{3} requires exactly three consecutive a characters for the match. The first group has only one:
a → Not enough
The second group has two:
aa → Not enough
The third group has three:
aaa → Match
It starts at index 5.
More examples of a{m}:
| Pattern | Meaning |
|---|---|
a{1} |
Exactly one a |
a{2} |
Exactly two consecutive a characters |
a{3} |
Exactly three consecutive a characters |
a{5} |
Exactly five consecutive a characters |
6. a{m,n} - Minimum m and Maximum n
The Quantifier:
a{m,n}
means:
Minimum
mand maximumnnumber of consecutiveacharacters.
For example:
a{2,3}
means:
Minimum = 2
Maximum = 3
Therefore, it can match:
aa
aaa
By default, this quantifier is greedy, so when both lengths are possible at the same position, Python prefers the longer allowed match.
Our target contains:
a | aa | aaa
The first group a contains only one a, so it does not satisfy the minimum requirement of 2. The second group aa contains two a characters, so it matches. The third group aaa contains three a characters, so it also matches.
Every Quantifier Output
The complete output of every Quantifier on the target string abaabaaab:
Pattern: a
0 ... a
2 ... a
3 ... a
5 ... a
6 ... a
7 ... a
Pattern: a+
0 ... a
2 ... aa
5 ... aaa
Pattern: a*
0 ... a
1 ...
2 ... aa
4 ...
5 ... aaa
8 ...
9 ...
Pattern: a?
0 ... a
1 ...
2 ... a
3 ... a
4 ...
5 ... a
6 ... a
7 ... a
8 ...
9 ...
Pattern: a{3}
5 ... aaa
Pattern: a{2,3}
2 ... aa
5 ... aaa
Complete Quantifier Comparison
| Pattern | Meaning | Example Matches | Can Match Empty? |
|---|---|---|---|
a |
Exactly one | a | No |
a+ |
One or more | a, aa, aaa... | No |
a* |
Zero or more | empty, a, aa, aaa... | Yes |
a? |
Zero or one | empty, a | Yes |
a{m} |
Exactly m | For m=3: aaa | Normally No |
a{m,n} |
Between m and n | For {2,3}: aa or aaa | Only if minimum is 0 |
Important Concept - Greedy Behaviour
Quantifiers such as:
+
*
{m,n}
are greedy by default.
This means they try to consume as many matching characters as the pattern permits.
Example:
Target = aaa
Pattern = a+
Python prefers:
aaa
rather than stopping after:
a
Similarly:
Pattern = a{2,3}
Target = aaa
matches:
aaa
because three is within the allowed range and is the longest possible match.
Empty Matches - Complete Concept
Among the basic Quantifiers discussed here:
a*
a?
can match an empty string because their minimum required number of a characters is zero.
| Pattern | Minimum Required | Empty Match? |
|---|---|---|
a |
1 | No |
a+ |
1 | No |
a* |
0 | Yes |
a? |
0 | Yes |
a{3} |
3 | No |
a{2,3} |
2 | No |
The basic rule is:
Minimum occurrence = 0
│
▼
Empty match is possible
Execution Flow
The complete execution flow of the Quantifier program:
Program Starts
│
▼
import re
│
▼
Select Pattern
│
├── a
├── a+
├── a*
├── a?
├── a{3}
└── a{2,3}
│
▼
Target String
"abaabaaab"
│
▼
re.finditer()
│
▼
Start Searching
from Left to Right
│
▼
Check Pattern at
Current Position
│
┌──┴───────────┐
│ │
Match Possible No Match
│ │
▼ ▼
Create Match Move Forward
Object
│
▼
Print start()
and group()
│
▼
Continue Search
│
▼
End of Target
│
▼
Program Ends
Execution Flow - a+
Target = abaabaaab Pattern = a+ Start │ ▼ Index 0 │ ▼ "a" found │ ▼ Match → a │ ▼ Next search starts after match │ ▼ Index 2 │ ▼ "aa" found │ ▼ Match → aa │ ▼ Continue │ ▼ Index 5 │ ▼ "aaa" found │ ▼ Match → aaa │ ▼ No more matching groups │ ▼ End
Execution Flow - a* with Empty Matches
Target = abaabaaab Pattern = a* Index 0 │ ▼ Match "a" │ ▼ Index 1 │ ▼ No a present but zero a is valid │ ▼ Empty Match │ ▼ Index 2 │ ▼ Match "aa" │ ▼ Index 4 │ ▼ Empty Match │ ▼ Index 5 │ ▼ Match "aaa" │ ▼ Index 8 │ ▼ Empty Match │ ▼ Index 9 │ ▼ End position Zero a is valid │ ▼ Empty Match │ ▼ End
Important Points
- Do not confuse
awitha+. The first matches oneaat a time, while the second can combine consecutiveacharacters. +means one or more,*means zero or more, and?means zero or one.- Because
*and?allow zero occurrences, they can produce empty matches. - An empty match is a valid match whose matched text is
"". - An empty output after the dots does not mean that the current non-
acharacter matched. It means zeroacharacters matched at that position. - The Regex engine can also produce a zero-length match at the end position of the string. For a string of length 9, the final end position is index
9, even though the final character itself is at index8. {m}specifies an exact number of occurrences, and{m,n}specifies a range from minimummto maximumn.- Quantifiers are greedy by default unless changed using other Regular Expression syntax.
- The target string used for the main Quantifier examples is
abaabaaab. - Understanding empty matches is especially important before learning the major functions of Python's
remodule.
- Quantifiers specify how many times a particular character or pattern should occur
- a+ means at least one a, while a* means zero or more a
- a? matches zero or one a, and a{m,n} matches between m and n occurrences
- a* and a? produce empty matches because their minimum required occurrence is zero
- Quantifiers such as +, *, and {m,n} are greedy by default - they match as many characters as possible