通配符匹配&替换 and/or 多个字符串通配符匹配

wildcard match & replace and/or multiple string wildcard matching

我有两个非常相关的问题:

我确信这些任务有算法,但是,我找不到任何有用的东西。

Python 库有 fnmatch 但这不支持我想做的事情。

有很多方法可以做到这一点,但我想出了以下方法,应该可以解决您的第一个问题。根据您的示例,我假设您不想匹配空格。

此函数将第一个传递的模式转换为正则表达式,并将传递的替换模式转换为适合 re.sub 函数的字符串。

import re

def replaceWildcards(string, pattern, replacementPattern):
    splitPattern = re.split(r'([*?])', pattern)
    splitReplacement = re.split(r'([*?])', replacementPattern)
    if (len(splitPattern) != len(splitReplacement)):
        raise ValueError("Provided pattern wildcards do not match")
    reg = ""
    sub = ""
    for idx, (regexPiece, replacementPiece) in enumerate(zip(splitPattern, splitReplacement)):
        if regexPiece in ["*", "?"]:
            if replacementPiece != regexPiece:
                raise ValueError("Provided pattern wildcards do not match")
            reg += f"(\S{regexPiece if regexPiece == '*' else ''})" # Match anything but whitespace
            sub += f"\{idx + 1}" # Regex matches start at 1, not 0
        else:
            reg += f"({re.escape(regexPiece)})"
            sub += f"{replacementPiece}"
    return re.sub(reg, sub, string)

示例输出:

replaceWildcards("aaa.txt xx.txt.txt aaa.bat", "*.txt", "*.doc")
# 'aaa.doc xx.txt.doc aaa.bat'

replaceWildcards("aaa10.txt a1.txt aaa23.bat", "a??.txt", "b??.doc")
# 'aab10.doc a1.txt aaa23.bat'

replaceWildcards("aaa10.txt a1-suffix.txt aaa23.bat", "a*-suffix.txt", "b*-suffix.doc")
# 'aaa10.txt b1-suffix.doc aaa23.bat'

replaceWildcards("prefix-2aaa10-suffix.txt a1-suffix.txt", "prefix-*a*-suffix.txt", "prefix-*b*-suffix.doc")
# 'prefix-2aab10-suffix.doc a1-suffix.txt

注意 f 字符串需要 Python >=3.6.