question:
You want to use wildcards commonly used in Unix shells (such as .py, Dat[0-9] .csv, etc.) to match text strings
solution:
The fnmatch module provides two functions - fnmatch() and fnmatchcase(), which can be used to achieve such matching. Usage is as follows:
>>> from fnmatch import fnmatch, fnmatchcase >>> fnmatch('foo.txt', '*.txt')
True
>>> fnmatch('foo.txt', '?oo.txt')
True
>>> fnmatch('Dat45.csv', 'Dat[0-9]*')
True
>>> names = ['Dat1.csv', 'Dat2.csv', 'config.ini', 'foo.py'] >>> [name for name in names if fnmatch(name, 'Dat*.csv')] ['Dat1.csv', 'Dat2.csv']
>>>
The fnmatch() function uses the underlying operating system's case-sensitive rules (which vary from system to system) to match patterns.
>>> # On OS X (Mac)
>>> fnmatch('foo.txt', '*.TXT') False
>>> # On Windows
>>> fnmatch('foo.txt', '*.TXT') True
>>>
If you care about this difference, you can use fnmatchcase() instead. It uses your pattern case matching exactly.
>>> fnmatchcase('foo.txt', '*.TXT') False
>>>
An often overlooked feature of these two functions is that they are also useful when working with strings that are not filenames.
addresses = [
'5412 N CLARK ST',
'1060 W ADDISON ST',
'1039 W GRANVILLE AVE',
'2122 N CLARK ST',
'4802 N BROADWAY',
]
You can write a list comprehension like this:
>>> from fnmatch import fnmatchcase
>>> [addr for addr in addresses if fnmatchcase(addr, '* ST')]
['5412 N CLARK ST', '1060 W ADDISON ST', '2122 N CLARK ST']
>>> [addr for addr in addresses if fnmatchcase(addr, '54[0-9][0-9] *CLARK*')] ['5412 N CLARK ST']
>>>
The fnmatch() function has matching capabilities somewhere between simple string methods and powerful regular expressions. This is usually a reasonable solution when only simple wildcards are needed for data processing operations.