2013-12-23 5 views
1

Что было бы лучшим способом разделить строку ниже "(x=1, y = 2, z = 3) (a = 1) (m = 4, n = 6, o = 2)", чтобы извлечь пары значений ключей в любую форму (список, dict и т. Д.)? Я заинтересован в (х, 1) (у, 2) (г, 3) и т.д ..Python regex based split

Ни один из ниже регулярных выражений (для извлечения данные в круглых скобках)

>>> re.findall('(.+)(.+)(.+)', '(abc)(def)(ghi)') 
[('(abc)(def)(gh', 'i', ')')] 
>>> re.findall('(.+)(.+)(.*)', '(abc)(def)(ghi)') 
[('(abc)(def)(ghi', ')', '')] 
>>> re.findall('(.+)(.+)(.+)', '(abc)(def)(ghi)') 
[('(abc)(def)(gh', 'i', ')')] 
>>> re.findall('(.+)(.+)(.)', '(abc)(def)(ghi)') 
[('(abc)(def)(gh', 'i', ')')] 
>>> re.findall('(.+)(.+)(...)', '(abc)(def)(ghi)') 
[('(abc)(def)(', 'g', 'hi)')] 
>>> re.findall(r'(.+)(.+)(...)', '(abc)(def)(ghi)') 
[('(abc)(def)(', 'g', 'hi)')] 
>>> re.findall(r'(.+)(.+)(.+)', '(abc)(def)(ghi)') 
[('(abc)(def)(gh', 'i', ')')] 
>>> re.findall(r'(.+)(.+)(.+?)', '(abc)(def)(ghi)') 
[('(abc)(def)(gh', 'i', ')')] 
>>> re.findall(r'(.*?)(.*?)(.+?)', '(abc)(def)(ghi)') 

EDIT: не Извиняюсь за не будучи ясно, группировка также имеет важное значение здесь, как [('x', 1), ('y', 2), ('z', 3)], [('a', 1)], [('m', 4), ('n' 6), ('o', 2)]

+2

Что вы попробовать? Пожалуйста, покажите свой код. – rednaw

+0

- это полный пример? или возможно, что присутствует какой-либо разумный формат отображения x = y? например (x = y, ..) {a = b; ...} – Enermis

+0

Есть ли какая-либо информация в группировках, которые нельзя отбрасывать? – wim

ответ

0

Вы не можете сделать это в одном из регулярных выражений, потому что вы хотите вложенную структуру в качестве результата. Спички регулярных выражений всегда плоские.

Однако с двумя регулярными выражениями это довольно легко сделать:

import re 
from pprint import pprint 

thestr = "(x=1, y = 2, z = 3) (a = 1) (m = 4, n = 6, o = 2)" 
groups = re.findall(r'\([^)]+\)', thestr) 
matches = [] 

for group in groups: 
    matches.append(re.findall(r'(\w+)\s*=\s*(\d+)', group)) 

pprint(matches) 

Выведет:

[[('x', '1'), ('y', '2'), ('z', '3')], 
[('a', '1')], 
[('m', '4'), ('n', '6'), ('o', '2')]] 
0

Вам просто нужно извлечь все слова и цифры, а затем zip() их там впоследствии использовать функцию dict() сделать словарем

Так Попробуйте это:

import re 
string = "(x=1, y = 2, z = 3) (a = 1) (m = 4, n = 6, o = 2)" 

stripped = ''.join(re.findall('\w+',string)) 
words= re.findall('\D+',stripped) 
numbers= map(int,re.findall('\d+',string)) 
print dict(zip(words,numbers)) 

Выход:

{'a': 1, 'm': 4, 'o': 2, 'n': 6, 'y': 2, 'x': 1, 'z': 3} 

EDIT:

как вы заявили, что группировка имеет важное значение, я предлагаю вам просто пронестись их только как словари не упорядочены.

print zip(words,numbers) 
#[('x', 1), ('y', 2), ('z', 3), ('a', 1), ('m', 4), ('n', 6), ('o', 2)] 

Однако вы можете использовать OrderedDict:

from collections import OrderedDict 

print OrderedDict(zip(words,numbers)) 
#OrderedDict([('x', '1'), ('y', '2'), ('z', '3'), ('a', '1'), ('m', '4'), ('n', '6'), ('o', '2')]) 
+0

OP - номера, хранящиеся в виде чисел или строк? –

+0

@ChristopherHarris «числа» уже были сохранены как часть одной строки – HamZa

+0

@ Кристофер Харрис хорошо исправил, что –

1

Предполагая, что синтаксис строки никогда не ошибается:

re.findall('([a-z]+)\s*=\s*([0-9]+)', 
      "(x=1, y = 2, z = 3) (a = 1) (m = 4, n = 6, o = 2)") 

Вы могли бы также вы finditer, если вы предпочитаете итератор.

0

Здесь вы идете. Полный код готов к работе:

>>> import re 
>>> pairs = "(x=1, y = 2, z = 3) (a = 1) (m = 4, n = 6, o = 2)" 
>>> pairs_map = [(m[1], m[2]) for m in re.findall(r"((\w+)\s*\=\s*(\w+))", pairs)] 
>>> pairs_map 
[('x', '1'), ('y', '2'), ('z', '3'), ('a', '1'), ('m', '4'), ('n', '6'), ('o', '2')] 
>>> dict(pairs_map) 
{'a': '1', 'm': '4', 'o': '2', 'n': '6', 'y': '2', 'x': '1', 'z': '3'} 

Должно быть прямо. Он соответствует всем вхождений

wordmaybe whitespace=maybe whitespaceword