Мне нужно сопоставить две строки с простыми подстановочными знаками:

"oh.my.*" соответствует "*.my.life", "oh.my.goodness" и "*.*.*", но не "in.my.house"

Единственный подстановочный знак - *, который заменяет строку любого символа (минус).

Я подумал об использовании fnmatch, но он не принимает подстановочные знаки в имени файла.

Есть код с регулярным выражением, который я использую сейчас - думаю, что-то попроще было бы лучше:

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)
1
ts. 16 Июл 2010 в 00:41

2 ответа

Лучший ответ

Это должно сработать для вас:

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

Как это работает:

  • Сначала разделите входы на ..
  • Если аргументы имеют другое количество компонентов, происходит немедленная ошибка.
  • В противном случае переберите компоненты и проверьте равенство.
  • Если любой из компонентов является *, это также считается успешным совпадением.
  • Если какой-либо компонент не соответствует, верните False, в противном случае верните True.
6
Mark Byers 15 Июл 2010 в 20:47

На всякий случай, если другие наткнутся на эту ветку (как и я), я предлагаю использовать модуль "fnmatch" (см. https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch02s03.html ) для сопоставления строк.

0
kenneho 9 Сен 2016 в 13:42