serhii.net

In the middle of the desert you can say anything you want

11 Aug 2022

Python fnmatch glob invalid expressions

Globs

fnmatch — Unix filename pattern matching — Python 3.10.6 documentation:

Similar to Unix shell ones but without special handling of path bits, identical otherwise, and much simpler than regex:

  • * matches everything
  • ? matches any single character
  • [seq] matches any character in seq
  • [!seq] matches any character not in seq

Use case

I have a list of names, I allow the user to select one or more by providing either a single string or a glob and returning what matches.

First it was two parameters and “if both are passed X takes precedence, but if it doesn’t have matches then fallback is used …”.

Realized that a simple string is a glob matching itself - and I can use the same field for both simplifying A LOT. The users who don’t know about globs can just do strings and everything’s fine. Still unsure if it’s a good idea, but nice to have as option.

Then - OK, what happens if his string is an invalid glob? Will this lead to a “invalid regex” type of exception?

Well - couldn’t find info about this, in the source code globs are converted to regexes and I see no exceptions raised, and couldn’t provoke any errors myself.

Globs with only mismatched brackets etc. always match themselves , but the best one:

>>> fnmatch.filter(['aa]ab','bb'],"aa]*a[bc]")
['aa]ab']

It ignores the mismatched bracket while correctly interpreting the matched ones!

So - I just have to care that a “name” doesn’t happen to be a correctly formulated glob, like [this one].

  1. If it’s a string and has a match, return that match
  2. Anything else is a glob, warn about globs if glob doesn’t have a match either. (Maybe someone wants a name literally containing glob characters, name is not there but either they know about globs and know it’s invalid now, or they don’t know about them - since they seem to use glob special characters, now it’s a good time to find out)
Nel mezzo del deserto posso dire tutto quello che voglio.