Why have regular expressions survived seven decades of technological disruption? Because coders who understand regular expressions have a massive advantage when working with textual data. They can write in a single line of code what takes others dozens!
This article is all about the
re.match() method of Python’s
re library. There are two similar methods to help you use regular expressions:
- The easy-to-use but less powerful
re.findall()method returns a list of string matches. Check out our blog tutorial.
re.search()method returns a match object of the first match. Check out our blog tutorial.
Related article: Python Regex Superpower – The Ultimate Guide
Do you want to master the regex superpower? Check out my new book The Smartest Way to Learn Regular Expressions in Python with the innovative 3-step approach for active learning: (1) study a book chapter, (2) solve a code puzzle, and (3) watch an educational chapter video.
So how does the
re.match() method work? Let’s study the specification.
How Does re.match() Work in Python?
re.match(pattern, string) method returns a match object if the
pattern matches at the beginning of the
string. The match object contains useful information such as the matching groups and the matching positions. An optional argument
flags allows you to customize the regex engine, for example to ignore capitalization.
re.match(pattern, string, flags=0)
re.match() method has up to three arguments.
pattern: the regular expression pattern that you want to match.
string: the string which you want to search for the pattern.
flags(optional argument): a more advanced modifier that allows you to customize the behavior of the function. Want to know how to use those flags? Check out this detailed article on the Finxter blog.
We’ll explore them in more detail later.
re.match() method returns a match object. You may ask (and rightly so):
What’s a Match Object?
If a regular expression matches a part of your string, there’s a lot of useful information that comes with it: What’s the exact position of the match? Which regex groups were matched—and where?
The match object is a simple wrapper for this information. Some regex methods of the
re module in Python—such as
re.match()—automatically create a match object upon the first pattern match.
At this point, you don’t need to explore the match object in detail. Just know that we can access the start and end positions of the match in the string by calling the methods
m.end() on the match object
>>> m = re.match('h...o', 'hello world') >>> m.start() 0 >>> m.end() 5 >>> 'hello world'[m.start():m.end()] 'hello'
In the first line, you create a match object
m by using the
re.match() method. The pattern
'h...o' matches in the string
'hello world' at start position 0. You use the start and end position to access the substring that matches the pattern (using the popular Python technique of slicing). But note that as the
match() method always attempts to match only at the beginning of the string, the
m.start() method will always return zero.
Now, you know the purpose of the
match() object in Python. Let’s check out a few examples of
A Guided Example for re.match()
First, you import the re module and create the text string to be searched for the regex patterns:
>>> import re >>> text = ''' Ha! let me see her: out, alas! he's cold: Her blood is settled, and her joints are stiff; Life and these lips have long been separated: Death lies on her like an untimely frost Upon the sweetest flower of all the field. '''
Let’s say you want to search the text for the string ‘her’:
>>> re.match('lips', text) >>>
The first argument is the pattern to be found: the string
'lips'. The second argument is the text to be analyzed. You stored the multi-line string in the variable text—so you take this as the second argument. The third argument
flags of the
match() method is optional.
There’s no output! This means that the
re.match() method did not return a match object. Why? Because at the beginning of the string, there’s no match for the regex pattern
So how can we fix this? Simple, by matching all the characters that precede the string
'lips' in the text:
>>> re.match('(.|\n)*lips', text) <re.Match object; span=(0, 122), match="\n Ha! let me see her: out, alas! he's cold:\n>
(.|\n)*lips matches all prefixes (an arbitrary number of characters including new lines) followed by the string
'lips'. This results in a new match object that matches a huge substring from position 0 to position 122. Note that the match object doesn’t print the whole substring to the shell. If you access the matched substring, you’ll get the following result:
>>> m = re.match('(.|\n)*lips', text) >>> text[m.start():m.end()] "\n Ha! let me see her: out, alas! he's cold:\n Her blood is settled, and her joints are stiff;\n Life and these lips"
Interestingly, you can also achieve the same thing by specifying the third flag argument as follows:
>>> m = re.match('.*lips', text, flags=re.DOTALL) >>> text[m.start():m.end()] "\n Ha! let me see her: out, alas! he's cold:\n Her blood is settled, and her joints are stiff;\n Life and these lips"
re.DOTALL flag ensures that the dot operator
. matches all characters including the new line character.
What’s the Difference Between re.match() and re.findall()?
There are two differences between the
re.match(pattern, string) and
re.findall(pattern, string) methods:
re.match(pattern, string)returns a match object while
re.findall(pattern, string)returns a list of matching strings.
re.match(pattern, string)returns only the first match in the string—and only at the beginning—while
re.findall(pattern, string)returns all matches in the string.
Both can be seen in the following example:
>>> text = 'Python is superior to Python' >>> re.match('Py...n', text) <re.Match object; span=(0, 6), match='Python'> >>> re.findall('Py...n', text) ['Python', 'Python']
'Python is superior to Python' contains two occurrences of
match() method only returns a match object of the first occurrence. The
findall() method returns a list of all occurrences.
What’s the Difference Between re.match() and re.search()?
re.search(pattern, string) and
re.match(pattern, string) both return a match object of the first match. However,
re.match() attempts to match at the beginning of the string while
re.search() matches anywhere in the string.
You can see this difference in the following code:
>>> text = 'Slim Shady is my name' >>> re.search('Shady', text) <re.Match object; span=(5, 10), match='Shady'> >>> re.match('Shady', text) >>>
re.search() method retrieves the match of the
'Shady' substring as a match object. But if you use the
re.match() method, there is no match and no return value because the substring
'Shady' does not occur at the beginning of the string
'Slim Shady is my name'.
How to Use the Optional Flag Argument?
As you’ve seen in the specification, the
match() method comes with an optional third
re.match(pattern, string, flags=0)
What’s the purpose of the
Flags allow you to control the regular expression engine. Because regular expressions are so powerful, they are a useful way of switching on and off certain features (for example, whether to ignore capitalization when matching your regex).
|If you don’t use this flag, the special Python regex symbols |
|Same as |
|If you use this flag, Python will print some useful information to the shell that helps you debugging your regex.|
|If you use this flag, the regex engine will perform case-insensitive matching. So, if you’re searching for character class |
|Same as |
|Don’t use this flag — ever. It’s depreciated—the idea was to perform case-insensitive matching depending on your current locale. But it isn’t reliable.|
|Same as re.LOCALE|
|This flag switches on the following feature: the start-of-the-string regex |
|Same as |
|Without using this flag, the dot regex |
|Same as |
|To improve the readability of complicated regular expressions, you may want to allow comments and (multi-line) formatting of the regex itself. This is possible with this flag: all whitespace characters and lines that start with the character |
|Same as |
Here’s how you’d use it in a practical example:
>>> text = 'Python is great!' >>> re.search('PYTHON', text, flags=re.IGNORECASE) <re.Match object; span=(0, 6), match='Python'>
Although your regex
'PYTHON' is all-caps, we ignore the capitalization by using the flag
Where to Go From Here?
This article has introduced the
re.match(pattern, string) method that attempts to match the first occurrence of the regex pattern at the beginning of a given string—and returns a match object.
Python soars in popularity. There are two types of people: those who understand coding and those who don’t. The latter will have larger and larger difficulties participating in the era of massive adoption and penetration of digital content. Do you want to increase your Python skills daily without investing a lot of time?
Then join my “Coffee Break Python” email list of tens of thousands of ambitious coders!
Google, Facebook, and Amazon engineers are regular expression masters. If you want to become one as well, check out our new book: The Smartest Way to Learn Python Regex (Amazon Kindle/Print, opens in new tab).
While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.
To help students reach higher levels of Python success, he founded the programming education website Finxter.com that has taught exponential skills to millions of coders worldwide. He’s the author of the best-selling programming books Python One-Liners (NoStarch 2020), The Art of Clean Code (NoStarch 2022), and The Book of Dash (NoStarch 2022). Chris also coauthored the Coffee Break Python series of self-published books. He’s a computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.
His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.