2015-07-10 12 views
5

Próbuję przeanalizować dane wyjściowe z polecenia mdls OS X. W przypadku niektórych kluczy wartość jest listą wartości. Muszę poprawnie przechwycić te kluczowe pary wartości. Wszystkie listy wartości zaczynają się od (, a kończą na ).Skutecznie zastępuj ciągi z wieloma wierszami za pomocą ciągów z jedną linią

Potrzebuję być w stanie powtórzyć wszystkie kluczowe pary wartości, aby poprawnie przeanalizować wiele wyników (np. mdls uruchomić wiele plików, aby utworzyć pojedyncze wyjście, gdzie nie ma rozróżnienia między końcem metadanych jednego pliku a drugi się zaczyna). Mam poniżej przykładowy kod.

Czy jest to skuteczniejszy sposób?

import re 

mdls_output = """kMDItemAuthors     = (
    margheim 
) 
kMDItemContentCreationDate  = 2015-07-10 14:41:01 +0000 
kMDItemContentModificationDate = 2015-07-10 14:41:01 +0000 
kMDItemContentType    = "com.adobe.pdf" 
kMDItemContentTypeTree   = (
    "com.adobe.pdf", 
    "public.data", 
    "public.item", 
    "public.composite-content", 
    "public.content" 
) 
kMDItemCreator     = "Safari" 
kMDItemDateAdded    = 2015-07-10 14:41:01 +0000 
""" 

mdls_lists = re.findall(r"^\w+\s+=\s\(\n.*?\n\)$", mdls_output, re.S | re.M) 
single_line_lists = [re.sub(r'\s+', ' ', x.strip()) for x in mdls_lists] 
for i, mdls_list in enumerate(mdls_lists): 
    mdls_output = mdls_output.replace(mdls_list, single_line_lists[i]) 
print(mdls_output) 
+0

Czy Twoje rozwiązanie działa? Czy pytasz o efektywną pamięć lub rozwiązanie, które jest * szybsze *? – wwii

+0

Działa, ale wydaje się niepotrzebnie skomplikowany. Ja * chcę *, aby zagnieździć dwa 're.sub's, ale nie mogłem tego zrobić; to znaczy, zamień listę wieloliniową na listę jednoliniową, która wymagałaby normalizacji białych znaków (np. 're.sub (r"^\ w + \ s + = \ s \ (\ n. *? \ n \) $ " , re.sub (r '\ s +', '', '\ 1'.strip(), mdls_output) ') – smargh

+0

Zwykle wygląda dobrze, ale twoje główne wyrażenie jest trochę nie tak. Prawdopodobnie powinno być' "^ \ w + \ s * = \ s * \ (\ n. *? \ n \) $ "'. Nie powinno to być 'mdls_output = mdls_output.replace (mdls_list [i], single_line_lists [i])'? – sln

Odpowiedz

2

Można wykorzystać Pythona regex substytut która może potrwać funkcję jako zamiennik ciąg. Funkcja jest wywoływana dla każdego dopasowania z obiektem dopasowania. Zwrócony ciąg zastępuje dopasowanie.

def myfn(m): 
    return re.sub(r'\s+', ' ', m.group().strip()) 

pat = re.compile(r"^\w+\s+=\s\(\n.*?\n\)$", re.S | re.M) 
mdls_output = pat.sub(myfn, mdls_output) 
+0

I * wiedział * musi być sposób, aby przekazać funkcję. Czytam przez "re" doktorzy, ale większość tego przegapiła. – smargh

Powiązane problemy