2015-07-10 13 views
5

Tôi đang cố phân tích đầu ra từ lệnh mdls của OS X. Đối với một số khóa, giá trị là danh sách các giá trị. Tôi cần phải nắm bắt các cặp khóa, giá trị này một cách chính xác. Tất cả danh sách giá trị bắt đầu bằng ( và sau đó kết thúc bằng ).Thay thế chuỗi danh sách nhiều dòng một cách hiệu quả bằng chuỗi danh sách đơn lẻ

Tôi cần có khả năng lặp qua tất cả các cặp khóa, giá trị sao cho tôi có thể phân tích cú pháp nhiều kết quả đầu ra (ví dụ: mdls chạy trên nhiều tệp để tạo ra một đầu ra duy nhất, nơi không có sự phân biệt giữa nơi siêu dữ liệu của một tệp kết thúc và của người kia bắt đầu). Tôi có một số mã mẫu dưới đây.

Có cách nào hiệu quả hơn để thực hiện việc này không?

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

Giải pháp của bạn có hoạt động không? Bạn có yêu cầu thay thế bộ nhớ hiệu quả hay giải pháp * nhanh hơn * không? – wwii

+0

Nó hoạt động, nhưng nó cảm thấy phức tạp không cần thiết. Tôi * muốn * làm tổ hai 're.sub's, nhưng tôi không thể làm được điều đó; có nghĩa là, thay thế danh sách đa dòng cho một danh sách một dòng, điều này sẽ yêu cầu bình thường hóa khoảng trống (ví dụ: 're.sub (r"^\ w + \ s + = \ s \ (\ n. *? \ n \) $ " , re.sub (r '\ s +', '', '\ 1'.strip(), mdls_output) ') – smargh

+0

Nó hầu như trông ok, nhưng regex chính của bạn là một chút sai. Có lẽ nên là' "^ \ w + \ s * = \ s * \ (\ n. *? \ n \) $ "'. Không nên là 'mdls_output = mdls_output.replace (mdls_list [i], single_line_lists [i])'? – sln

Trả lời

2

Bạn có thể tận dụng lợi thế của regex thay python có thể mất một chức năng như chuỗi thay thế. Hàm được gọi cho mỗi đối sánh với đối tượng đối sánh. Chuỗi trả về sẽ thay thế kết quả khớp.

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

Tôi * biết * phải có một cách để vượt qua một chức năng.Tôi đọc qua 're' tài liệu, nhưng hầu hết đã bỏ lỡ điều này. – smargh

Các vấn đề liên quan