2012-06-19 3 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 comprehension; Мне это нравится! – 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

Пожалуйста, следуйте фрагментам кода с некоторыми деталями, разъяснениями, чтобы быть более понятными для читателей. –

 Смежные вопросы

  • Нет связанных вопросов^_^