2013-02-14 36 views
5

Tôi muốn yêu cầu trợ giúp của bạn.Python: regex để bắt dữ liệu

Tôi có một mảnh lớn dữ liệu, mà trông như thế này:

 a 
    b : c 901 
    d : e sda 
v 
    w : x ads 
    any 
    abc : def 12132 
    ghi : jkl dasf 
    mno : pqr fas 
    stu : vwx utu 

Mô tả: tập tin bắt đầu với một dòng chứa đơn từ (nó có thể bắt đầu với khoảng trắng và khoảng trắng có thể cũng sau chữ), sau đó sau dòng thuộc tính được phân tách bằng dấu hai chấm (cũng có thể có khoảng trắng), sau đó lại một lần nữa các thuộc tính hoặc dòng với một từ duy nhất. Tôi không thể tạo ra các regex quyền bắt nó ở dạng như:

{ 
    "a": [["b": "c 901"], ["d", "e sda"]], 
    "v": [["w", "x ads"]], 
    "any": ["abc", "def 12132"], ["ghi", "jkl dasf"], 
    # etc. 
} 

Dưới đây là những gì tôi đã cố gắng:

regex = str() 
regex += "^(?:(?:\\s*)(.*?)(?:\\s*))$", 
regex += "(?:(?:^(?:\\s*)(.*?)(?:\\s*):(?:\\s*)(.*?)(?:\\s*))$)*$" 
pattern = re.compile(regex, re.S | re.M) 

Tuy nhiên, nó không tìm thấy những gì tôi cần. Bạn có thể giúp tôi? Tôi biết tôi có thể xử lý tệp mà không cần regex, sử dụng trình lặp dòng và kiểm tra biểu tượng ":", nhưng tệp quá lớn để xử lý theo cách này (nếu bạn biết cách xử lý nhanh mà không cần regex, điều này cũng sẽ câu trả lời đúng, nhưng đầu tiên mà đến trong tâm trí là quá chậm).

Cảm ơn trước!

P.S. Trong hình thức kinh điển của tập tin trông như thế này:

a 
    b : c 901 
    d : e sda 

Mỗi phần bắt đầu bằng một từ duy nhất, sau đó làm theo các thuộc tính dòng (sau hai khoảng trắng), có các thuộc tính được tách ra với (":"), sau đó agane thuộc tính dòng hoặc dòng với một từ duy nhất. Các khoảng trống khác đều bị cấm. Có lẽ nó sẽ dễ dàng hơn.

+0

+1 Siêu Clarity; Câu hỏi đóng khung gọn gàng. – Yavar

Trả lời

3

Cụm từ thông dụng có thực sự cần thiết ở đây không? Hãy thử mã giả này:

result = {} 

last = None 
for _line in data: 
    line = _line.strip().split(":") 
    if len(line) == 1: 
     last = line[ 0 ] 
     if last not in result: 
      result[ last ] = [] 
    elif len(line) == 2: 
     obj = [ line[ 0 ].strip(), line[ 1 ].strip() ] 
     result[ last ].append(obj) 

Tôi hy vọng tôi hiểu chính xác cấu trúc dữ liệu của bạn.

+2

Đây là cách tiếp cận chính xác, không cần regex, tôi đã có câu trả lời ở đây tôi đã xóa vì nó không phải là không cần thiết, đây là giải pháp bạn cần. (có thể cần một chút chỉnh sửa - nhưng điều bạn muốn) +1 –

0

Bạn có thể sử dụng regex này ..

(?:[\n\r]+|^)\s*(\w+)\s*[\n\r]+(\s*\w+\s*:\s*.*?)(?=[\n\r]+\s*\w+\s*[\n\r]+|$) 

Bạn cần phải trận đấu trên regex với singleline hoặc dotall tùy chọn

Group1 và GROUP2 phù hợp với những gì bạn muốn mỗi lần bạn kết hợp

hãy xem here ..sử dụng chấm tất cả tùy chọn

0
# a more golf - like solution 
from itertools import groupby 

groups = groupby(map(lambda s: map(str.strip,s.split(':')), data), len) 
dict((next(i[1])[0], list(next(groups)[1])) for i in groups) 

ra:

{'a': [['b', 'c 901'], ['d', 'e sda']], 
'any': [['abc', 'def 12132'], 
    ['ghi', 'jkl dasf'], 
    ['mno', 'pqr fas'], 
    ['stu', 'vwx utu']], 
'v': [['w', 'x ads']]} 
Các vấn đề liên quan