【问题标题】:strings with wildcards matching通配符匹配的字符串
【发布时间】:2010-07-15 20:41:34
【问题描述】:

我需要用简单的通配符匹配两个字符串:

"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)

【问题讨论】:

  • 应该oh.* 匹配oh.my.goodness 还是* 不能匹配点?在您的所有示例中,点的数量始终相同。
  • * 无法完全匹配点。
  • @ts:哦,现在我看到你已经在你的问题中提到了,我只是在第一次阅读时错过了它。

标签: python regex string


【解决方案1】:

这应该适合你:

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。

【讨论】:

  • 更干净、更简单。我现在正在测试性能,但我想它会比正则表达式好得多
  • @ts:如果性能是一个严重的问题并且您想要稍微快一点的东西,那么仍然有一些可用的选项。例如,如果所有调用的两个参数之一都相同,您可以只拆分一次并将拆分数组作为参数而不是原始字符串传递。
  • 我做了一些优化。看来你的方法快了 +/- 2 倍
  • 嗯,这是一个奇怪的想法。如果其中一个字符串较短但另一个字符串有'.*'后缀怎么办?说 'oh.my.*' 和 '*.my' - 不应该匹配吗?
  • 应该。事实上,我也修改了马克的代码来做到这一点。它会额外检查 len(aa) != len(bb) 是否以 '*' 结尾
【解决方案2】:

以防其他人偶然发现这个线程(就像我一样),我建议使用“fnmatch”模块(参见https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch02s03.html)进行字符串匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-04
    • 2015-07-29
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多