2015-03-14 2 views
1

Я знаю, что есть много вопросов с тем же названием. Моя ситуация немного отличается. У меня есть строка, как:Извлечь данные из круглых скобок в python

"Cat(Money(8)Points(80)Friends(Online(0)Offline(8)Total(8)))Mouse(Money(10)Points(10000)Friends(Online(10)Offline(80)Total(90)))"

(Обратите внимание, что есть скобка вложен в другой)

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

d["Cat"]["Money"] == 8 
d["Cat"]["Points"] = 80 
d["Mouse"]["Friends"]["Online"] == 10 

и скоро. Я хотел бы сделать это без библиотек и регулярных выражений. Если вы решите использовать их, пожалуйста, объясните код очень подробно. Спасибо заранее!

Edit:

Хотя этот код не будет иметь никакого смысла, это то, что я до сих пор:

o_str = "Jake(Money(8)Points(80)Friends(Online(0)Offline(8)Total(8)))Mouse(Money(10)Points(10000)Friends(Online(10)Offline(80)Total(90)))" 
spl = o_str.split("(") 
def reverseIndex(str1, str2): 
    try: 
     return len(str1) - str1.rindex(str2) 
    except Exception: 
     return len(str1) 
def app(arr,end): 
    new_arr = [] 
    for i in range(0,len(arr)): 
     if i < len(arr)-1: 
      new_arr.append(arr[i]+end) 
     else: 
      new_arr.append(arr[i]) 
    return new_arr 

spl = app(spl,"(") 
ends = [] 
end_words = [] 
op = 0 
cl = 0 
for i in range(0,len(spl)): 
    print i 
    cl += spl[i].count(")") 
    op += 1 
    if cl == op-1: 
     ends.append(i) 
     end_words.append(spl[i]) 
     #break 
    print op 
    print cl 
    print 
print end_words 

Конечные слова секции в начале каждого оператора. Я планирую использовать рекурсивный, чтобы сделать все остальное.

+0

Это похоже на вопрос о домашнем задании, поэтому вы должны опубликовать то, что вы сделали до сих пор, и что конкретно вы испытываете проблемы. – paidhima

+0

Regex действительно кажется лучшим способом сделать это. Вероятно, '\ w + \ ((\ d +) \)' – pangeacake

+0

@paidhima Это не домашнее задание. Если бы я опубликовал все, что я пробовал до сих пор, это не имело бы для вас никакого смысла. Однако я отправлю его, как только я получу доступ к своему рабочему столу. –

ответ

1

было интересно. Вы действительно nerd-sniped меня на этом ...

def parse(tokens): 
    """ take iterator of tokens, parse to dictionary or atom """ 
    dictionary = {} 
    # iterate tokens... 
    for token in tokens: 
     if token == ")" or next(tokens) == ")": 
      # token is ')' -> end of dict; next is ')' -> 'leaf' 
      break 
     # add sub-parse to dictionary 
     dictionary[token] = parse(tokens) 
    # return dict, if non-empty, else token 
    return dictionary or int(token) 

Установка и демонстрация:

>>> s = "Cat(Money(8)Points(80)Friends(Online(0)Offline(8)Total(8)))Mouse(Money(10)Points(10000)Friends(Online(10)Offline(80)Total(90)))" 
>>> tokens = iter(s.replace("(", " (").replace(")", ") ").split()) 
>>> pprint(parse(tokens)) 
{'Cat': {'Friends': {'Offline': 8, 'Online': 0, 'Total': 8}, 
     'Money': 8, 
     'Points': 80}, 
'Mouse': {'Friends': {'Offline': 80, 'Online': 10, 'Total': 90}, 
      'Money': 10, 
      'Points': 10000}} 

В качестве альтернативы, вы можете также использовать ряд строковых замен, чтобы превратить эту строку в фактический Python словарной строки, а затем оценить это, например например:

as_dict = eval("{'" + s.replace(")", "'}, ") 
         .replace("(", "': {'") 
         .replace(", ", ", '") 
         .replace(", ''", "")[:-3] + "}") 

Это будет обертывать «листья» в одиночных наборах строк, например. {'8'} вместо 8, но это должно быть легко исправить на этапе последующей обработки.

+0

Что такое атом? –

+0

@jakekimds Я имел в виду «атомный» элемент в словаре или лист, т. Е. Числа в вашем случае. –

+0

Надеюсь, вы не были посреди дороги, когда вы читаете это: http://xkcd.com/356/ –

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