假设这两组字符串:
file=sheet-2016-12-08.xlsx file=sheet-2016-11-21.xlsx file=sheet-2016-11-12.xlsx file=sheet-2016-11-08.xlsx file=sheet-2016-10-22.xlsx file=sheet-2016-09-29.xlsx file=sheet-2016-09-05.xlsx file=sheet-2016-09-04.xlsx size=1024KB size=22KB size=980KB size=15019KB size=202KB
file=sheet-2016-*.xlsx size=*KB
数据集可以是任何字符串集.它不必匹配格式.这是另一个例子:
id.4030.paid id.1280.paid id.88.paid
预期产量为:
id.*.paid
基本上,我需要一个函数来分析一组字符串,并用星号(*)替换不常见的子字符串
解决方法
您可以使用os.path.commonprefix来计算公共前缀.它用于计算文件路径列表中的共享目录,但可以在通用上下文中使用.
然后反转字符串,再次应用公共前缀,然后反向,计算公共后缀(改编自https://gist.github.com/willwest/ca5d050fdf15232a9e67)
dataset = """id.4030.paid id.1280.paid id.88.paid""".splitlines() import os # Return the longest common suffix in a list of strings def longest_common_suffix(list_of_strings): reversed_strings = [s[::-1] for s in list_of_strings] return os.path.commonprefix(reversed_strings)[::-1] common_prefix = os.path.commonprefix(dataset) common_suffix = longest_common_suffix(dataset) print("{}*{}".format(common_prefix,common_suffix))
结果:
id.*.paid
编辑:正如Wim所说:
>当所有字符串相等时,公共前缀和&后缀是相同的,但它应该返回字符串本身而不是前缀*后缀:应检查所有字符串是否相同
>当共同前缀&后缀重叠/有共享字母,这也会混淆计算:应该计算字符串上的公共后缀减去公共前缀
因此,需要一个多合一的方法来预先测试列表,以确保至少2个字符串是不同的(在过程中缩小前缀/后缀公式),并使用切片计算公共后缀以删除公共前缀:
def compute_generic_string(dataset): # edge case where all strings are the same if len(set(dataset))==1: return dataset[0] commonprefix = os.path.commonprefix(dataset) return "{}*{}".format(commonprefix,os.path.commonprefix([s[len(commonprefix):][::-1] for s in dataset])[::-1])
现在让我们测试一下:
for dataset in [['id.4030.paid','id.1280.paid','id.88.paid'],['aBBc','aBc'],[]]: print(compute_generic_string(dataset))
结果:
id.*.paid aB*c *
(当数据集为空时,代码返回*,也许这应该是另一个边缘情况)