通配符匹配&替换和/或多个字符串通配符匹配



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

  • 我想用通配符匹配字符串模式(即包含一个或多个'*'或'?')然后用第二个通配符模式形成一个替换字符串。在这里,占位符应该指向与相同的匹配的子字符串(例如在DOS复制命令中)

    示例:pattern='*.txt'replacement-pattern='*.doc':我想要aaa.txt—>aaa.docxx.txt.txt—>xx.txt.doc

    理想情况下,它可以使用多个任意放置的通配符:例如,pattern='*.*'replacement-pattern='XX*.*'

    当然需要应用一些约束(例如贪心策略)。否则,X*X*X等模式对于字符串XXXXXX不是唯一的。

  • 或者,形成多重匹配。也就是说,我有一个或多个通配符模式,每个模式具有相同数量的通配符。每个模式与一个字符串匹配,但通配符应该指向相同的匹配文本。

    示例:pattern1='*.txt'pattern2='*-suffix.txt应该匹配对string1='XX.txt'string2='XX-suffix.txt',但不是string1='XX.txt'string2='YY-suffix.txt'

    与第一个问题相比,这是一个定义更明确的问题,因为它避免了歧义问题,但可能非常相似。

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

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-string需要Python>=3.6.

相关内容

  • 没有找到相关文章

最新更新