【问题标题】:Inverse glob - reverse engineer a wildcard string from file namesInverse glob - 从文件名逆向工程通配符字符串
【发布时间】:2017-10-04 03:55:29
【问题描述】:

我想从一对文件名中生成一个通配符字符串。一种逆球体。示例:

file1 = 'some foo file.txt'
file2 = 'some bar file.txt'
assert 'some * file.txt' == inverse_glob(file1, file2)

也许使用difflib?这个问题已经解决了吗?

应用程序是一组具有相似名称的数据文件。我想比较每对文件名,然后比较具有“相似”名称的文件对。我想如果我可以在每一对上做一个反向全局,那么那些带有“好”通配符的对(例如不是lots*of*stars*.txt 也不是*)是比较好的候选者。因此,我可能会采用这个假定的 inverse_glob() 的输出,并拒绝具有多个 *glob() 不会产生两个文件的通配符。

【问题讨论】:

  • 这个问题的通用解决方案可能不是很容易找到。您谈论文件名相似。最有可能找到一个更简单的解决方案,利用这一点。或许你可以举一些典型文件名的例子?
  • @JohanL 感谢您跳出框框思考。我想把这篇文章的重点放在全局逆策略上,所以这个问题对后代更有用。我确实将问题简化为 2 个文件,你说得对,它的通用性和简单性要低得多。回答一下,我在野外的文件在不同的地方以不同的方式存在差异,例如"filename.txt" and "filename2.txt" or "the 24MHz run new.sr" and "the 16MHz run old.sr"

标签: python filenames glob


【解决方案1】:

例如:

文件名

names = [('some foo file.txt','some bar file.txt', 'some * file.txt'),
         ("filename.txt", "filename2.txt", "filenam*.txt"),
         ("1filename.txt", "filename2.txt", "*.txt"),
         ("inverse_glob", "inverse_glob2", "inverse_glo*"),
         ("the 24MHz run new.sr", "the 16MHz run old.sr", "the *MHz run *.sr")]

def inverse_glob(...)

    import re
    def inverse_glob(f1, f2, force_single_asterisk=None):
        def adjust_name(pp, diff):
            if len(pp) == 2:
                return pp[0][:-diff] + '?'*(diff+1) + '.' + pp[1]
            else:
                return pp[0][:-diff] + '?' * (diff + 1)

        l1 = len(f1); l2 = len(f2)
        if l1 > l2:
            f2 = adjust_name(f2.split('.'), l1-l2)
        elif l2 > l1:
            f1 = adjust_name(f1.split('.'), l2-l1)

        result = ['?' for n in range(len(f1))]
        for i, c in enumerate(f1):
            if c == f2[i]:
                result[i] = c

        result = ''.join(result)
        result = re.sub(r'\?{2,}', '*', result)
        if force_single_asterisk:
            result = re.sub(r'\*.+\*', '*', result)
        return result

用法

for name in names:
    result = inverse_glob(name[0], name[1])
    print('{:20} <=> {:20} = {}'.format(name[0], name[1], result))
    assert name[2] == result

输出

some foo file.txt    <=> some bar file.txt    = some * file.txt  
filename.txt         <=> filename2.txt        = filenam*.txt  
1filename.txt        <=> filename2.txt        = *.txt  
inverse_glob         <=> inverse_glob2        = inverse_glo*
the 24MHz run new.sr <=> the 16MHz run old.sr = the *MHz run *.sr

用 Python:3.4.2 测试

【讨论】:

    猜你喜欢
    • 2011-07-14
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 2012-05-31
    • 2021-08-23
    • 2011-11-17
    • 2022-01-22
    • 2011-11-18
    相关资源
    最近更新 更多