Rahul Thakkar
Rahul Thakkar

Reputation: 1

Regex returning empty list when trying to capture an optional group

I am trying to capture the board after every hand of a poker game. Each hand has a summary section in which the board is summarized as follows:

string = "*** SUMMARY ***Total pot Rupees 971.44 | Rake Rupees 46.24Board [2s Qh 8s 7c]Seat 1: lesterr276 folded before Flop (didn't bet)Seat 2: davinder125 folded on the TurnSeat 3: ProfessorOfCard (button) collected (Rupees 925.20)Seat 4: warmachine1997 (small blind) folded before FlopSeat 6: harsha164 (big blind) folded on the Turn"

As you can see the Board was [2s Qh 8s 7c] in the above hand. Now a lot of hands end before the flop, in which case there is no board. Hence, the board may or may not be a part of the summary.

I want the regex to capture the board if it is present in the Summary or return a None object if it is not present. I have used the following code to capture the board and it works fine:

re.search(r'\*{1,} SUMMARY \*{1,}.*?(Board (.*?\]))', string).group(1)

But when I add a "?" to make the board group optional, it does not work as expected and returns an empty object:

 re.search(r'\*{1,} SUMMARY \*{1,}.*?(Board (.*?\]))?', string).group(1)

What am I doing wrong?

Upvotes: 0

Views: 31

Answers (1)

joanis
joanis

Reputation: 12229

What happens is that you have .*? just before Board that is also trying to match as short a string as possible. When Board is required for a match, it stretches to just before it. But when Board is no longer required, the RE engine will get a match with the preceding .*? matching zero characters and your optional Board expression empty, at which point the engine stops, since it found a match.

I would solve this problem by using two regular expressions in and if/else block: if the regex requiring board matches, use its results, otherwise use a different regex for when Board is missing.

Something like this:

match = re.search(r'\*{1,} SUMMARY \*{1,}.*?(Board (.*?\]))', string)
if match:
    board = match.group(1)
else:
    board = ""
    # use the alternative RE for the rest

Upvotes: 2

Related Questions