import re

class BettingRound:
    def __init__(self, lines):
        self.cards = []
        self.actions = []
        _round_name_re = re.compile(r"^([A-Z ]+) \*\*\*.*$")
        _street_cards_re = re.compile(r"\*\*\*.*\[(.+)\]")
        _hole_cards_re = re.compile(r".*Card dealt to a spot \[(.*)\]")
        match = _round_name_re.match(lines[0])
        self.round_name = match.group(1)
        if '[' in lines[0]:
            match = _street_cards_re.match(lines[0])
            self.cards = match.group(1).split()
        for L in lines[1:]:
            if 'Card dealt to a spot' in L:
                assert not '[' in lines[0] # assert not flop/turn/riv
                match = _hole_cards_re.match(L)
                self.cards.append(match.group(1).split()) # list of lists
            elif ('Seat sit down' in L
                  or 'Table deposit' in L
                  or 'Seat stand' in L
                  or 'Table enter user' in L):
                continue
            elif ' : ' in L:
                self.actions.append(L)
            else:
                print('*** unhandled line:' + L)
    def __repr__(self):
        return str(self.__dict__)

class Hand:
    def __init__(self, string):
        segments = "seats preflop flop turn river".split()
        _hand_num_re = re.compile(r"^Ignition Hand #(\d+) .*$")
        self.seats = None
        self.preflop = None
        self.flop = None
        self.turn = None
        self.river = None
        self.summary = None
        ## step 2: split each hand into segments
        s = string.split('\n*** ')
        while len(s) > 1:
            # We don't always have flop, turn, riv, but last element is
            # always Summary.
            k = segments.pop(0)
            ## step 3: split each segment into lines
            v = s.pop(0).splitlines()
            self.__dict__[k] = v
        self.summary = s.pop(0).splitlines()
        assert len(s) == 0
        ## step 4: parse various elements at sub-line level
        match = _hand_num_re.match(self.seats[0])
        self.hand_number = int(match.group(1))
    def __repr__(self):
        return str(self.__dict__)


## main

input = open('example_ignition.txt').read()

## step 1: split flat file into hands
hands = input.split('\n\n\n')

for i, h in enumerate(hands):
    hands[i] = Hand(h)

## [ { s:[] p:[] f:[] s:[] }  { s:[] p:[] f:[] t:[] r:[] s:[] }  {}  {} ]

print(hands[0])

@@ -210,27 +210,88 @@
 e(r%22
-%5C*%5C*%5C*
 .*%5C%5B(.
-+
+*
 )%5C%5D
+.*
 %22)%0A
+        # hits only last %5BKh%5D construct because 1st * is greedy.%0A
     
@@ -474,16 +474,53 @@
 nes%5B0%5D:%0A
+            # only for flop/turn/riv%0A
         
@@ -1035,16 +1035,61 @@
 er user'
+ in L%0A                  or 'Table leave user'
  in L):%0A
@@ -1959,32 +1959,160 @@
 0).splitlines()%0A
+            if k in %22preflop flop turn river%22.split():%0A                self.__dict__%5Bk%5D = BettingRound(v)%0A            else:%0A    
             self

Use new class in practice.