Skip to content

fnmatch

The Python fnmatch module provides Unix shell-style wildcard pattern matching for filename strings. It uses a small set of special characters to match names without the complexity of full regular expressions.

Here’s a quick look at filtering a list of filenames by pattern:

Language: Python
>>> import fnmatch

>>> files = [
...     "notes.txt",
...     "data.csv",
...     "readme.md",
...     "report.txt",
...     "image.png"
... ]
>>> fnmatch.filter(files, "*.txt")
['notes.txt', 'report.txt']

Key Features

  • Supports four wildcard characters: *, ?, [seq], and [!seq]
  • fnmatch() follows platform case rules via os.path.normcase() (case-insensitive on Windows, case-sensitive on Unix)
  • fnmatchcase() always performs a case-sensitive match regardless of platform
  • filter() efficiently returns all matching names from an iterable, backed by the module-wide compiled-pattern cache that fnmatch(), fnmatchcase(), and filterfalse() also share
  • translate() converts a wildcard pattern to an equivalent regular expression string
  • Doesn’t treat the path separator / specially, so use glob for full pathname expansion
  • Treats leading periods as ordinary characters, so * and ? match dotfiles, unlike glob

Pattern Syntax

Pattern Matches
* Any sequence of characters, including an empty sequence
? Any single character
[seq] Any single character in seq
[!seq] Any single character not in seq

To match a literal *, ?, or [, wrap it in brackets: [*], [?], [[].

Frequently Used Classes and Functions

Object Type Description
fnmatch.fnmatch() Function Tests whether a filename matches a pattern using platform case rules
fnmatch.fnmatchcase() Function Tests whether a filename matches a pattern with case-sensitive comparison on all platforms
fnmatch.filter() Function Returns the subset of names from an iterable that match a pattern
fnmatch.filterfalse() Function Returns the subset of names from an iterable that do not match a pattern, available since Python 3.14
fnmatch.translate() Function Converts a wildcard pattern to a regular expression string for use with re

Examples

Demonstrating all four wildcard characters:

Language: Python
>>> import fnmatch

>>> fnmatch.fnmatch("report.txt", "*.txt")
True
>>> fnmatch.fnmatch("data_2024.csv", "data_????.csv")
True
>>> fnmatch.fnmatch("log_a.txt", "log_[abc].txt")
True
>>> fnmatch.fnmatch("log_d.txt", "log_[!abc].txt")
True

Using fnmatchcase() for consistent case-sensitive matching across platforms:

Language: Python
>>> import fnmatch

>>> fnmatch.fnmatchcase("Report.TXT", "*.txt")
False
>>> fnmatch.fnmatchcase("report.txt", "*.txt")
True

Converting a wildcard pattern to a regular expression with translate():

Language: Python
>>> import fnmatch, re

>>> regex = fnmatch.translate("*.txt")
>>> regex
'(?s:.*\\.txt)\\z'
>>> bool(re.match(regex, "report.txt"))
True
>>> bool(re.match(regex, "report.csv"))
False

Common Use Cases

The most common tasks for fnmatch include:

  • Filtering lists of filenames returned by os.listdir() or os.scandir()
  • Matching filenames against multiple patterns in a loop
  • Building tools that accept shell-style wildcard arguments from users
  • Converting wildcard rules into regular expressions for more complex matching logic

Real-World Example

The following script uses fnmatch.filter() to sort a list of log filenames into categories:

Language: Python Filename: log_sorter.py
import fnmatch

log_files = [
    "app_jan01.log",
    "app_jan02.log",
    "err_jan01.log",
    "app_feb01.log",
    "debug.log",
    "access.log",
]

jan_logs = fnmatch.filter(log_files, "app_jan??.log")
err_logs = fnmatch.filter(log_files, "err_*.log")
all_app = fnmatch.filter(log_files, "app_*.log")

print("January logs:", jan_logs)
print("Error logs:", err_logs)
print("All app logs:", all_app)

Run it from the command line:

Language: Shell
$ python log_sorter.py
January logs: ['app_jan01.log', 'app_jan02.log']
Error logs: ['err_jan01.log']
All app logs: ['app_jan01.log', 'app_jan02.log', 'app_feb01.log']

The ? wildcard in app_jan??.log matches exactly two characters of any kind in the day-number position, while * in the other patterns matches any sequence of characters.

Python 3 "pathlib" Module: Taming The Filesystem

Tutorial

Python's pathlib Module: Taming the File System

Handle file and folder paths the modern way with Python pathlib, a built-in module whose semantics work the same on every OS.

intermediate python stdlib

For additional information on related topics, take a look at the following resources:

Have a question about this? Mentor AI can show you examples, compare related terms, and point you to tutorials.


By Leodanis Pozo Ramos • Updated Sept. 23, 2026