ts.
ts.

Reputation: 10709

strings with wildcards matching

I need to match two strings with simple wildcards:

"oh.my.*" matches "*.my.life", "oh.my.goodness" and "*.*.*", but not "in.my.house"

The only wildcard is *, which substitutes string of any character (minus .)

I thought of using fnmatch, but it does not accept wildcards in file name.

There is some code with regex which i am using now - something simpler would be better, i guess:

def notify(self, event, message):
    events = []
    r = re.compile(event.replace('.','\.').replace('*','[^\.]+'))
    for e in self._events:
        if r.match(e):
            events.append(e)
        else:
            if e.find('*')>-1:
                r2 = re.compile(e.replace('.','\.').replace('*','[^\.]+'))
                if r2.match(event):
                    events.append(e)
    for event in events:
        for callback in self._events[event]:
            callback(self, message)

Upvotes: 1

Views: 5797

Answers (2)

kenneho
kenneho

Reputation: 421

Just in case others stumble upon this thread (like I did), I suggest using the "fnmatch" module (see https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch02s03.html) for string matching.

Upvotes: 0

Mark Byers
Mark Byers

Reputation: 838146

This should work for you:

def is_match(a, b):
    aa = a.split('.')
    bb = b.split('.')
    if len(aa) != len(bb): return False
    for x, y in zip(aa, bb):
        if not (x == y or x == '*' or y == '*'): return False
    return True

How it works:

  • First split the inputs on ..
  • If the arguments have a different number of components then fail immediately.
  • Otherwise iterate over the components and check for equality.
  • If either component is a * this also counts as a successful match.
  • If any component fails to match return False, otherwise return True.

Upvotes: 6

Related Questions