Reverse Globe - Reverse engineering a wildcard from file names

I want to create a wildcard from a pair of file names. A kind of reverse globe. Example:

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

Is it possible to use difflib ? Has this been decided yet?

An application is a large set of data files with similar names. I want to compare each pair of file names, and then introduce a comparison of file pairs with "similar" names. I believe that if I can make a reverse globe on each pair, then these pairs with “good” wildcards (for example, not lots*of*stars*.txtand *) are good candidates for comparison. Therefore, I can take the output of this supposed one inverse_glob()and reject the wildcards that have more than one *or for which it glob()does not create exactly two files.

+3
source share
1 answer

For example:

File names

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

Using

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

+2

All Articles