2015-07-10 15 views
5

OS X'in mdls komutundan çıktı ayrıştırmaya çalışıyorum. Bazı tuşlar için değer, değerlerin bir listesidir. Bu anahtarı, değer çiftlerini doğru bir şekilde yakalamam gerekiyor. Tüm değerler listesi ( ile başlar ve ) ile sona erer.Çok satırlı liste dizelerini tek satırlık dizili dize ile değiştirin

Birden çok çıktıyı düzgün bir şekilde ayrıştırabilmem için tüm anahtar, değer çiftlerini yineleyebilmem gerekir (örneğin, bir dosyanın meta verileri nerede bittiği arasında hiçbir ayrım olmadığı tek bir çıktı oluşturmak için birden çok dosyada çalıştırılabilir (mdls) ve diğeri başlıyor). Aşağıda bazı örnek kod var.

Bunu yapmanın daha verimli bir yolu var mı?

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

Çözümünüz çalışıyor mu? Hafıza verimli bir alternatif mi yoksa daha hızlı * olan bir çözüm mü istiyorsunuz? – wwii

+0

Çalışıyor, ancak gereksiz yere karmaşık geliyor. Ben * iki * re.sub's yuvalamak istiyorum *, ama bunu işe alamadım; yani, boşluk satırının normalleştirilmesini gerektiren tek satırlı bir liste için çok satırlı listenin yerini al (ör. "re.sub (r"^\ w + \ s + = \ s \ (\ n. *? \ n \) $ " , re.sub (r '\ s +', '', '\ 1'.strip(), mdls_output) ') – smargh

+0

Çoğunlukla iyi görünüyor, ancak ana regexiniz biraz yanlış. Muhtemelen' '^ \ w + olmalıdır \ s * = \ s * \ (\ n. *? \ n \) $ "'. Bunun olması mdls_output = mdls_output.replace (mdls_list [i], single_line_lists [i]) '? – sln

cevap

2

Yerini alan dizeye olarak bir işlev alabilir Python en regex yerine yararlanabilir. Eşleşme nesnesiyle her eşleşme için işlev çağrılır. Döndürülen dizi eşleşmeyi değiştirir.

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 * biliyordum * bir işlevi geçmek için bir yol olmalı. docs, ama çoğu bunu kaçırdı. – smargh

İlgili konular