Yotam
Yotam

Reputation: 10685

How to search for multiple conditions in python regex?

I'm writing a helper script for DnD needs, part of the script should accept either integers or dice notation. The latter is in the format of

1d20+4

where I can replace 1, 20 with and natural number, and +4 with any integer. The input can look like

hit +3 damage 1d8+1 hp 3d6+2

And I split it into two list using re. The problem is that when I try to detect both dies and numbers. I know that that to detect a number I need to use

re.listall('[\+\-][0-9]*',input_line)

and to detect a die I need to search for

re.listall('[0-9]*d[0-9]*',input_line)

And I'm quite certain that to search for a die with a bonus I need

re.listall('[0-9]*d[0-9]*[\+\-][0-9]*',input_line)

However, I can't figure how to search for a combination of the two. I though about placing them in parenthesis, i.e.

re.listall('([\+\-][0-9]*)([0-9]*d[0-9]*)',input_line)

However, I get an error sre_constants.error: unbalanced parenthesis

which leaves me confused. How can I overcome this?

Upvotes: 1

Views: 13522

Answers (2)

Kasravnd
Kasravnd

Reputation: 107287

You can use to following regex with re.findall(),Note that as certainly you have a number in your pattern you can put \d{1,} within combinations of word characters and +- :

>>> s ='hit +3 damage 1d8+1 hp 3d6+2'
>>> re.findall(r'([\S+-]*\d{1,}[\S+-]*)+',s)
['+3', '1d8+1', '3d6+2']

Regular expression visualization

Debuggex Demo

Upvotes: 1

Julien Spronck
Julien Spronck

Reputation: 15423

I think that what you need is this regular expression:

re.findall('((\d+d\d+)?[\+-]\d+)', input_line)

As a side note, you can use \d instead of [0-9]. So, the second part is the same as in your code. The first part '(\d+d\d+)?' is optional (because of ?) and matches number followed by the letter d followed by a number.

In your example (hit +3 damage 1d8+1 hp 3d6+2), this will match +3, 1d8+1 and 3d6+2

Upvotes: 1

Related Questions