Multiple-regex-checking Python One-liner

Published Mar 14, 2020 · Updated Mar 10, 2026

Python programming language logo with code illustration

Well, this might be kind of cheating but I did find it to be a useful tool for an assignment I got in my Python class. I had to check that a string matches a certain set of criterias (e.g. has lowercase letters, uppercase letters and so on [and yes, it IS a password checker]).

The map() Approach — When You Need to Know Which Patterns Matched

In order to achieve this I have imported the re module and have precompiled the individual regular expressions so that my code is a bit more modular. I have also used string.punctuation to make a regular expression checking for special characters.

import re
import string

lowercase_regex = re.compile("[a-z]")
uppercase_regex = re.compile("[A-Z]")
special_regex = re.compile('[' + re.escape(string.punctuation) + ']')
numbers_regex = re.compile("[0-9]")

This is nice and all but how am I going to compare all of those regular expressions against a single string? I could do a for loop but that seems like unnecessary complication. I have decided to use the map() function along with a re.findall() lambda and match the string against all regexes one after the other.

By doing that, we get a list of lists (after converting the map object, of course) containing the matches to each one of the regular expressions, and we can easily know which regular expression did not match (by checking if the respective index in the list is an empty list) and act accordingly.

Let’s see it in action. First, I’ll put the relevant regular expressions I want to check the string against in a list so that map() can iterate through it, and the I’ll call I’ll do some magic and eventually check the list.

>>> password = "Hello"
>>> password_regex = [lowercase_regex, uppercase_regex, numbers_regex, special_regex]
>>> password_regex_matches_list = list(map(lambda regex: re.findall(regex, password), password_regex))
>>> password_regex_matches_list
[['e', 'l', 'l', 'o'], ['H'], [], []]

Here you can see that the string “Hello” returned 4 matches for the 1st regex, which checked for lowercase letters, then 1 match for the uppercase regex and no matches for the other 2 (numbers and special characters).

Bonus: If you’d like to know how many matches there are in total, you can do this easily by iterating through to list of list with itertools.chain simply import it and run through the list.

>>> from itertools import chain
>>> password_regex_matches = list(chain.from_iterable(password_regex_matches_list))
>>> password_regex_matches
['e', 'l', 'l', 'o', 'H']

And that’s it, you’ve unpacked the list and can access all matches!

The any() / all() Approach — When You Just Need a Yes or No

The map() approach is great when you need the full picture — like showing the user exactly which password requirements they’re missing. But sometimes you just want a boolean: does this string match all (or any) of my patterns?

For that, a generator expression with all() or any() is cleaner:

>>> patterns = [lowercase_regex, uppercase_regex, numbers_regex, special_regex]

# True only if ALL patterns match
>>> all(re.search(p, password) for p in patterns)
False  # "Hello" has no numbers or special characters

# True if ANY pattern matches
>>> any(re.search(p, password) for p in patterns)
True  # "Hello" matches lowercase and uppercase

Short, readable, and no import of itertools. The tradeoff is you lose the per-pattern detail — you know the answer is “no” but not why. Pick your approach based on what you actually need:

Quick Note: re.search vs re.match vs re.findall

Since these come up a lot when working with multiple patterns, here’s the quick version:

For most multi-pattern checks, re.search is your friend. It’s the most forgiving of the three and behaves the way you’d intuitively expect.

If you liked this post, you can find all of my other content right here

~/categories/Programming, Python
~/tags/Programming, Python, Regex, Regular Expressions