如何解决通配符匹配和替换和/或多个字符串通配符匹配
我有两个非常相关的问题:
-
我想用通配符匹配一个字符串模式(即包含一个或多个“*”或“?”) 然后用第二个通配符模式形成一个替换字符串。那里的占位符应该引用 same 匹配的子字符串 (以DOS复制命令为例)
示例:
pattern='*.txt'
和replacement-pattern='*.doc'
: 我想要aaa.txt
-->aaa.doc
和xx.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 字符串需要 Python >=3.6。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。