2012-06-19 59 views
5

我對Python很新,我試圖解析一個文件。只有文件中的某些行包含感興趣的數據,並且我最終需要從文件中的有效匹配行解析出來的東西的字典。從Python成功的正則表達式匹配生成字典

下面的代碼工作,但它有點難看,我試圖瞭解它應該如何完成,也許有理解,或者與多行正則表達式。我正在使用Python 3.2。

file_data = open('x:\\path\\to\\file','r').readlines() 
my_list = [] 
for line in file_data: 
    # discard lines which don't match at all 
    if re.search(pattern, line): 
     # icky, repeating search!! 
     one_tuple = re.search(pattern, line).group(3,2) 
     my_list.append(one_tuple) 
my_dict = dict(my_list) 

您能否提出更好的實施方案?

+2

理解可能很漂亮,但是你不能輕易地將一個變量綁定到它們內部的值,所以你需要雙重的're.search'。只需使用一個循環。 –

回答

4

感謝您的答覆。把它們放在一起後,我得到了

file_data = open('x:\\path\\to\\file','r').read() 
my_list = re.findall(pattern, file_data, re.MULTILINE) 
my_dict = {c:b for a,b,c in my_list} 

但我不認爲我今天可以得到那裏沒有幫助。

+2

你可能想讓你的第一個組在正則表達式中不捕獲('?:')來跳過理解步驟:'my_dict = dict(re.findall ...)' – georg

+0

相當不錯的改進。但是:將所有數據讀入一個變量,而不是遍歷一個文件對象(並且隱式地調用'readline()'方法),這是不可擴展的。 're.findall()'在迭代器而不是變量上工作得很好。 – smci

4

下面是一些quick'n'dirty的優化你的代碼:

my_dict = dict() 

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     match = re.search(pattern, line) 
     if match: 
      one_tuple = match.group(3, 2) 
      my_dict[one_tuple[0]] = one_tuple[1] 
+0

謝謝,這有助於 – WiringHarness

1

我不知道我會推薦它,但這裏有一個方法,你可以嘗試使用,而不是理解(我取代的字符串爲簡便起見,文件)

>>> import re 
>>> data = """1foo bar 
... 2bing baz 
... 3spam eggs 
... nomatch 
... """ 
>>> pattern = r"(.)(\w+)\s(\w+)" 
>>> {x[0]: x[1] for x in (m.group(3, 2) for m in (re.search(pattern, line) for line in data.splitlines()) if m)} 
{'baz': 'bing', 'eggs': 'spam', 'bar': 'foo'} 
+0

Dict理解;我喜歡! – WiringHarness

2

EAFP精神,我建議

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     try: 
      m = re.search(pattern, line) 
      my_dict[m.group(2)] = m.group(3) 
     except AttributeError: 
      pass 

另一種方法是繼續使用列表,但重新設計模式,以便它只包含兩個組(key, value)。那麼你可以簡單地做:

matches = [re.findall(pattern, line) for line in data] 
    mydict = dict(x[0] for x in matches if x) 
+0

findall是有幫助的。 – WiringHarness

1
matchRes = pattern.match(line) 
if matchRes: 
    my_dict = matchRes.groupdict() 
+0

請按照您的代碼片段的一些細節,爲讀者解釋更清楚。 –