2015-07-10 5 views
5

के साथ मल्टी-लाइन सूची स्ट्रिंग को कुशलता से प्रतिस्थापित करें मैं ओएस एक्स के mdls कमांड से आउटपुट पार्स करने का प्रयास कर रहा हूं। कुछ कुंजियों के लिए, मान मानों की एक सूची है। मुझे इन कुंजी, मूल्य जोड़े को सही तरीके से कैप्चर करने की आवश्यकता है। मानों की सभी सूचियां ( से शुरू होती हैं और फिर ) के साथ समाप्त होती हैं।एकल_लाइन सूची स्ट्रिंग

मुझे सभी कुंजी, मूल्य जोड़े पर पुन: सक्रिय करने में सक्षम होना चाहिए ताकि मैं एक आउटपुट उत्पन्न करने के लिए एकाधिक आउटपुट (यानी mdls एकाधिक फ़ाइलों पर चलने के लिए सही ढंग से पार्स कर सकूं, जहां एक फ़ाइल के मेटाडेटा समाप्त होने के बीच कोई भेद नहीं है और दूसरा शुरू होता है)। मेरे पास नीचे कुछ नमूना कोड है।

क्या ऐसा करने के लिए एक और अधिक प्रभावी तरीका है?

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

क्या आपका समाधान काम करता है? क्या आप मेमोरी कुशल विकल्प या समाधान के लिए पूछ रहे हैं जो * तेज * है? – wwii

+0

यह काम करता है, लेकिन यह अनावश्यक रूप से जटिल लगता है। मैं * चाहता हूं * दो 're.sub' घोंसला, लेकिन मैं इसे काम करने के लिए नहीं मिल सका; यानी, एक सिंगल-लाइन सूची के लिए मल्टीलाइन सूची को प्रतिस्थापित करें, जिसमें व्हाइटस्पेस को सामान्यीकृत करने की आवश्यकता होगी (उदाहरण के लिए 're.sub (r "^ \ w + \ s + = \ s \ (\ n। *? \ n \) $" , re.sub (r '\ s +', '', '\ 1'.strip(), mdls_output) ') – smargh

+0

यह ज्यादातर ठीक दिखता है, लेकिन आपका मुख्य रेगेक्स थोड़ा गलत है। शायद"^^ w + होना चाहिए \ s * = \ s * \ (\ n। *? \ n \) $ "'। 'वह नहीं होना चाहिए' mdls_output = mdls_output.replace (mdls_list [i], single_line_lists [i]) '? – sln

उत्तर

2

आप अजगर के regex विकल्प का लाभ जो प्रतिस्थापन स्ट्रिंग रूप एक समारोह ले जा सकते हैं ले जा सकते हैं। समारोह को प्रत्येक वस्तु के लिए मैच ऑब्जेक्ट के साथ बुलाया जाता है। लौटाई गई स्ट्रिंग मैच को बदल देती है।

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

मुझे पता था * फ़ंक्शन पास करने का कोई तरीका होना चाहिए। मैंने 're' दस्तावेज़, लेकिन अधिकांश ने इसे याद किया है। धन्यवाद। – smargh

संबंधित मुद्दे