2012-06-19 57 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

请按照您的代码片段的一些细节,为读者解释更清楚。 –