2017-05-05 64 views
3

我想從一對文件名中生成通配符字符串。一種逆水滴。例如:反向glob - 從文件名反向設計通配符字符串

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()的輸出並拒絕具有多個*或其中​​3210不會生成恰好兩個文件的通配符。

+0

這個問題的一般解決方案可能不是很容易找到。你談論的文件名是相似的。利用這一點很可能找到更簡單的解決方案。也許你可以舉一些典型的文件名的例子嗎? – JohanL

+0

@JohanL謝謝你在盒子外面思考。我想把這篇文章的重點放在glob-inverse策略上,所以這個問題對後人更有用。我的確把問題簡化成了2個文件,你說得對,就不那麼一般了,簡單得多。爲了回答,我野外的文件在不同的地方以不同的方式有所不同,例如, 「filename.txt」和「filename2.txt」或「24MHz run new.sr」和「16MHz run old.sr」 –

回答

2

例如:

文件名

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")] 

高清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