2017-04-03 2 views
0

eine Liste von Dateien in einem Verzeichnis Gegeben:lesen oder eine Datei öffnen "fuzzy match" Dateinamen mit - Python

import os 
os.listdir('system-outputs/newstest2016/ru-en') 

[out]:

['newstest2016.AFRL-MITLL-contrast.4524.ru-en', 
'newstest2016.AFRL-MITLL-Phrase.4383.ru-en', 
'newstest2016.AMU-UEDIN.4458.ru-en', 
'newstest2016.NRC.4456.ru-en', 
'newstest2016.online-A.0.ru-en', 
'newstest2016.online-B.0.ru-en', 
'newstest2016.online-F.0.ru-en', 
'newstest2016.online-G.0.ru-en', 
'newstest2016.PROMT-Rule-based.4277.ru-en', 
'newstest2016.uedin-nmt.4309.ru-en'] 

Und dann habe ich den Eingang:

filename, suffix = 'newstest2016.AFRL-MITLL-contrast', 'ru-en' 

den Dateinamen verwenden, wenn ich eine solche Regex tun wollen, dass ich newstest2016.AFRL-MITLL-contrast.4524.ru-en die Datei lesen kann, könnte ich tun:

import re 
fin = open(next(_fn for _fn in os.list('system-outputs/newstest2016/ru-en') if re.match(filename + '.*.' + suffix, _fn) for _fn in)) 

Aber gibt es eine Möglichkeit, einen "fuzzy match" Dateinamen zu lesen/öffnen? Es muss einen besseren Weg geben als das rohe re.match Weg oben.

Es ist in Ordnung, davon auszugehen, dass immer eine eindeutige Übereinstimmung von der os.listdir vorliegt.

+1

Was würden Sie als "eindeutige Übereinstimmung" definieren? Eine Fuzzy-Übereinstimmung kann per Definition mehrere Elemente zusammenbringen, so dass das Implementieren einer solchen Sache sehr unwahrscheinlich ist, wenn die Unschärfe nicht genau definiert ist. –

+0

Da ist diese "4524" Nummer in "news test2016.AFRL-MITLL-contrast.4524.ru-de", von der ich vorher nichts weiß, also versucht die Regex das zu erraten. – alvas

+0

Wenn es Präfix basiert wie Sie vorschlagen, werfen Sie einen Blick auf die Antwort gegeben. Für mich sieht es so aus, als ob du ''. '' Willst. Join (filename.split ('.') [: - 2]) '. –

Antwort

5

Ich glaube glob könnte ein besserer Weg sein.

0

Sie können glob wie vorgeschlagen verwenden, aber es kann mehrere Übereinstimmungen geben. Ich würde mit dem Muster gehen, das zu sein scheint:

für schönere Syntax
filenames = [ 
    'newstest2016.AFRL-MITLL-contrast.4524.ru-en', 
    # ... 
    'newstest2016.PROMT-Rule-based.4277.ru-en', 
    'newstest2016.uedin-nmt.4309.ru-en' 
] 
my_filename, suffix = 'newstest2016.AFRL-MITLL-contrast', 'ru-en' 
for filename in filenames: 
    *fn, suff = filename.split('.') 
    if ('.'.join(fn[:-1]), suff) == (my_filename, suffix): 
     break 
else: 
    filename = None 
# `filename` is now set to real file name 

Ich benutze python3.x aber das ist einfach zu portieren Python2.x.

+0

Da Sie die Schleife bei der korrekten Übereinstimmung (mit einer "streng single match" Info) brechen, erwarte ich, dass dies für große Dateinamenlisten schneller sein sollte. Können Sie bitte einige Benchmarks hinzufügen? Auf einer (fernen) Randnotiz bin ich nicht derjenige, der deine Antwort abgelehnt hat! – 0xc0de

+0

Nicht sicher, dass hier Benchmarks benötigt werden. Wenn dies ein Prozess ist, der schnell sein sollte, einige Preprocessing und die Verwendung von Mappings (und die Tatsache, dass Keys ein 'Set' sind), würde es viel besser machen, deshalb sehe ich keinen Sinn beim Benchmarking :-) –

Verwandte Themen