Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 17, 2015 16:49:33

romensd
Зарегистрирован: 2015-06-05
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

нужна регулярка которая умеет извлекать текст из скобок по уровню
для этого я буду использовать рекурсию

исходная строка
level_1<level_2<level_3,level_3<level_4,level_4>>,level_2<level_3,level_3>>

на 1 этапе получить строку в скобках level_1
level_2<level_3,level_3<level_4,level_4>>,level_2<level_3,level_3>
на 2 этапе получить строку в скобках level_2
level_3,level_3<level_4,level_4>
level_3,level_3 - конец рекурсии

на 3 этапе получить строку в скобках level_3
level_4,level_4 - конец рекурсии

в скобках <> может быть:
1. строка level_n
2. level_1< level_2>
3. level_1< level_2,level_2>
4. level_1< level_2<level_n,…>,level_2>


вопрос в том как корректно извлекать сроки относительно уровня вложенности

Офлайн

#2 Июнь 17, 2015 22:04:03

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

Почему нужна именно регулярка, а не что-нибудь другое?

Офлайн

#3 Июнь 17, 2015 22:30:17

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

Регулярные выражения для этого плохо подходят. Посмотрите pyparsing



Офлайн

#4 Июнь 23, 2015 12:03:01

romensd
Зарегистрирован: 2015-06-05
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

Пример кода можно на pyparsing ?

Офлайн

#5 Июнь 23, 2015 12:21:40

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

Офлайн

#6 Июнь 23, 2015 19:24:15

romensd
Зарегистрирован: 2015-06-05
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

как распарсить строку
level_1<level_2_1<level_3,level_3_1<level_4,level_4_1>>,level_2_2<level_3,level_3_1_1>>
так, чтобы образовался вложений словарь
{“level_1” : {“level_2_1” : {“level_3”:{},“level_3_1”:{“level_4”:{},“level_4”:{}}} , “level_2_2”:{“level_3”:{},“level_3_1”:{}}}}

Отредактировано romensd (Июнь 23, 2015 19:30:02)

Офлайн

#7 Июнь 24, 2015 03:15:41

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

#!/usr/bin/env python3
 
"""
Convert:
 
level_1<level_2_1<level_3,level_3_1<level_4,level_4_1>>,level_2_2<level_3,level_3_1_1>>
 
To:
 
{'level_1':
    {'level_2_1':
        {'level_3': {},
         'level_3_1':
            {'level_4': {},
             'level_4': {}}},
     'level_2_2':
         {'level_3': {},
          'level_3_1': {}}}}
 
"""
 
import re
 
def make_tokens(s):
    pat = r'level[_\d]+|<|,|>'
    out = []
    for i in re.findall(pat, s):
        if i.startswith('level'):
            out.append(('name', i))
        elif i == '<':
            out.append(('open', i))
        elif i == ',':
            out.append(('sep', i))
        elif i == '>':
            out.append(('close', i))
    return out
 
def make_tree(tokens):
    out = []
    stack = []
    cur = out
    for t, v in tokens:
        if t == 'name':
            cur.extend([v, []])
        elif t == 'open':
            stack.append(cur)
            cur = cur[-1]
        elif t == 'close':
            cur = stack.pop()
        elif t == 'sep':
            pass
    return out
 
 
s = 'level_1<level_2_1<level_3,level_3_1<level_4,level_4_1>>,level_2_2<level_3,level_3_1_1>>'
 
out = make_tree(make_tokens(s))
 
import pprint
pprint.pprint(out)

[guest@localhost py]$ ./synt.py 
['level_1',
['level_2_1',
['level_3', [], 'level_3_1', ['level_4', [], 'level_4_1', []]],
'level_2_2',
['level_3', [], 'level_3_1_1', []]]]
[guest@localhost py]$


Словари не являются упорядоченными, поэтому последовательность элементов может меняться произвольно, и не может быть одинаковых ключей .
>>> {'level_1':
...     {'level_2_1':
...         {'level_3': {},
...          'level_3_1':
...             {'level_4': {},
...              'level_4': {}}},
...      'level_2_2':
...          {'level_3': {},
...           'level_3_1': {}}}}
{'level_1': {'level_2_2': {'level_3': {}, 'level_3_1': {}}, 'level_2_1': {'level_3': {}, 'level_3_1': {'level_4': {}}}}}
>>>



Отредактировано py.user.next (Июнь 24, 2015 11:48:47)

Офлайн

#8 Июнь 24, 2015 08:50:56

romensd
Зарегистрирован: 2015-06-05
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

как возможно написать парсер который возвращает количество чилдренов

level_1<
      level_2_1<
		  level_3,
		  level_3_1<level_4,level_4_1>>,
      level_2_2<level_3,level_3_1_1>

В level_1 их два (level_2_1,level_2_2) и т.д.

кортеж ('уровень' , ‘количество чилдренов’)
повторение уровней не важны
[
  (level_1, 2)
  (level_2_1,2),
  (level_2_2,2),
  (level_3,0)
  (level_3_1,2)
  (level_4,0)
  (level_4_1,0)
  (level_3,0)
  (level_3_1,1)
]

В парсер желательно не привязываться к слову level.
Строку я написал для примера, могут быть другие слова.
Количество чилдренов может быть разная.
Пока большое спасибо, очень помогли.

Отредактировано romensd (Июнь 24, 2015 09:07:42)

Офлайн

#9 Июнь 24, 2015 09:17:43

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

#!/usr/bin/env python3
 
"""
Convert:
 
level_1<level_2_1<level_3,level_3_1<level_4,level_4_1>>,level_2_2<level_3,level_3_1_1>>
 
To:
 
{'level_1':
    {'level_2_1':
        {'level_3': {},
         'level_3_1':
            {'level_4': {},
             'level_4': {}}},
     'level_2_2':
         {'level_3': {},
          'level_3_1': {}}}}
 
"""
 
import re
 
def make_tokens(s):
    pat = r'level[_\d]+|<|,|>'
    out = []
    for i in re.findall(pat, s):
        if i.startswith('level'):
            out.append(('name', i))
        elif i == '<':
            out.append(('open', i))
        elif i == ',':
            out.append(('sep', i))
        elif i == '>':
            out.append(('close', i))
    return out
 
def make_tree(tokens):
    out = []
    stack = []
    cur = out
    for t, v in tokens:
        if t == 'name':
            cur.extend([v, []])
        elif t == 'open':
            stack.append(cur)
            cur = cur[-1]
        elif t == 'close':
            cur = stack.pop()
        elif t == 'sep':
            pass
    return out
 
def make_children(tree):
    out = []
    name = ''
    for i in tree:
        if isinstance(i, str):
            name = i
        elif isinstance(i, list):
            out.append((name, len(i) // 2))
            out.extend(make_children(i))
    return out
 
 
s = 'level_1<level_2_1<level_3,level_3_1<level_4,level_4_1>>,level_2_2<level_3,level_3_1_1>>'
 
tree = make_tree(make_tokens(s))
out = make_children(tree)
 
import pprint
pprint.pprint(out)

[guest@localhost py]$ ./synt.py 
[('level_1', 2),
('level_2_1', 2),
('level_3', 0),
('level_3_1', 2),
('level_4', 0),
('level_4_1', 0),
('level_2_2', 2),
('level_3', 0),
('level_3_1_1', 0)]
[guest@localhost py]$

Обход другой немного. Так хоть понятно, что в чём находится.



Отредактировано py.user.next (Июнь 24, 2015 11:48:22)

Офлайн

#10 Июнь 24, 2015 09:42:35

romensd
Зарегистрирован: 2015-06-05
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения вложенные структуры

Очень круто . Большое спасибо

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version