rubik
rubik

Reputation: 9104

Negating a fnmatch pattern

Consider this pattern: *.py. It matches all the paths ending with the py extension. Now, is it possible to find a pattern which matches everything else?

I thought this would do it: *[!.][!p][!y], but apparently fnmatch.fnmatch always returns False with this.

I'd like to avoid regexes. I know I could use them, but in this case it isn't possible.

Upvotes: 5

Views: 8487

Answers (3)

panofish
panofish

Reputation: 7889

If files is a list of files, then this code will exclude all files matching *.py pattern using fnmatch.filter. This should be the correct answer.

exclude = '*.py'
for f in fnmatch.filter(files, exclude):
    files.remove(f)

Upvotes: 0

Kyle Strand
Kyle Strand

Reputation: 16499

I believe that the only absolutely correct answer is to generate the list of unwanted files, then find the difference between this list and the complete (unfiltered) file list. (This technique can be seen here, using set: https://stackoverflow.com/a/8645326/1858225)

There does not appear to be any built-in option for negating the search pattern in the fnmatch module.

For an example of why character-wise negation won't work, see my comment on user590028's answer.

Upvotes: 3

user590028
user590028

Reputation: 11730

I personally prefer regex, but if you'd prefer fnmatch, you could do:

if fnmatch.fnmatch(file, '*[!p][!y]'):
        print(file)

Upvotes: 5

Related Questions