Попробуйте использовать регулярное выражение для чтения вложенной структуры - PullRequest
0 голосов
/ 06 февраля 2019

Я пытаюсь прочитать следующую структуру (python):

a1a:bb2b,c3cc,dd44d;e5eee:ff66,g7;h8h:i9

(без пробелов между ними!), Чтобы в идеале вывести что-то вроде

((a1a, (bb2b, c3cc, dd44d)),
 (e5eee, (ff66, g7)),
 (h8h, (i9)))

Со словами: 1 или более групп.Каждая группа с одной головой, за которой следуют ":" и один или несколько элементов, разделенных ",".Группы разделены знаком ";".Каждый элемент буквенно-цифровой, включая "_".

Я попробовал следующее регулярное выражение (благодаря вкладу четвертой птицы (?:; | $)):

(\w+):(?:(\w+)|(?:,(\w+)(?=,))|(?:,(\w+)))+(?:;|$)

какпоказано здесь

Это дает такой результат:

((a1a, bb2b, c3cc, dd44d),
 (e5eee, ff66, g7),
 (h8h, i9))

Это лучше, чем ничего, но пока не точный формат вывода, как было запрошено.

Есть ли у кого-нибудьидея, как настроить регулярное выражение, чтобы получить точно желаемый результат?Боюсь, что вообще невозможно получить вложенные группы, такие как (bb2b, c3cc, dd44d), как это было бы в (a1a, (bb2b, c3cc, dd44d)), не так ли?

Заранее спасибо за любой намек.mdew

1 Ответ

0 голосов
/ 06 февраля 2019

Вы можете использовать 2 группы захвата с последующим сопоставлением точки с запятой или конца строки.Тогда в замене вы можете использовать те группы, объединяя их с круглыми скобками:

(\w+):(\w+(?:,\w+)*)(?:;|$)

Regex demo | Python demo

Объяснение

  • (\w+) Захват 1+ слов в группе
  • :Совпадение :
  • ( Группа захвата
    • \w+(?:,\w+)* Совпадение 1+ символов слова, за которыми следует группа, которая повторяет 0+ раз запятую и 1+ слова
  • ) закрыть группу
  • (?:;|$) Совпадение ; или конец строки

При замене вы можете использовать это, и они удаляютзавершающая запятая и новая строка

(\1(\2)),\n

Редактировать:

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

import re
text = "a1a:bb2b,c3cc,dd44d;e5eee:ff66,g7;h8h:i9"
matches = re.findall("(\w+):(\w+(?:,\w+)*)(?:;|$)", text)
matches  = list(map(lambda x: (x[0], tuple(x[1].split(','))), matches))
print (matches)

Результат:

[('a1a', ('bb2b', 'c3cc', 'dd44d')), ('e5eee', ('ff66', 'g7')), ('h8h', ('i9',))]

См. Python demo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...