tags:

views:

77

answers:

2

I have strings like "5d4h2s", where I want to get 5, 4, and 2 from that string, but I also want to know that 5 was paired with d, and that 4 was paired with h, etc etc. Is there an easy way of doing this without parsing char by char?

+8  A: 

If your input does not get more complicated than 5d4h2s:

>>> import re
>>> s = "5d4h2s"
>>> p = re.compile("([0-9])([a-z])")
>>> for m in p.findall(s):
...   print m
... 
('5', 'd')
('4', 'h')
('2', 's')

And if it gets, you can easily adjust the regular expression, e.g.

>>> p = re.compile("([0-9]*)([a-z])")

to accept input like:

>>> s = "5d14h2s"

Finally, you can condense the regex to:

>>> p = re.compile("([\d]+)([dhms])")
The MYYN
I wonder which of these is faster; I was tempted to use regular expressions but generally don't if I don't have to, but I'm sure the double list comprehension isn't particularly swift either
Michael Mrozek
mmh, just benchmarked it; with a precompiled pattern, the regex is actually a bit faster .. see this gist: http://gist.github.com/421540
The MYYN
You could use \d and \d+ in place of the [0-9] and[0-9]*.
Pierce
Thank you, added.
The MYYN
@The Good, yours is faster **and** not wrong :D
Michael Mrozek
A: 

For time string, you can try the following:

m = re.match("(\d+d)?(\d+h)?(\d+m)?(\d+s)?", "5d4h2s")
print m.group(1) # Days
print m.group(2) # Hours
print m.group(3) # Minutes
print m.group(4) # Seconds
print int(m.group(1)[:-1]) # Days, number
hudolejev