I wanted to correct the vartec's solution.
And then, from one correction to another, I finally modified the algorithm, and obtained:
# first code
import re
ncitems = 'farm011 - farm018, farm020, farm022 - farm033, farm041 - farm052'
print 'ncitems :\n',ncitems,'\n\n'
items = []
pat = re.compile("(\w+)(?<!\d)(\d+)(?:[ -]+(\w+)(?<!\d)(\d+))* *(?:,|\Z)")
for w1,s,w2,e in pat.findall(ncitems):
print '(w1,s,w2,e)==',(w1,s,w2,e)
items.extend( ("%s%03d"%(w1,i) for i in range(int(s),int(e)+1))
if w2
else ("%s%s"%(w1,s),) )
print '\nitems :\n',items
result
ncitems :
farm011 - farm018, farm020, farm022 - farm033, farm041 - farm052
(w1,s,w2,e)== ('farm', '011', 'farm', '018')
(w1,s,w2,e)== ('farm', '020', None, None)
(w1,s,w2,e)== ('farm', '022', 'farm', '033')
(w1,s,w2,e)== ('farm', '041', 'farm', '052')
items :
['farm011', 'farm012', 'farm013', 'farm014', 'farm015', 'farm016', 'farm017', 'farm018', 'farm020', 'farm022', 'farm023', 'farm024', 'farm025', 'farm026', 'farm027', 'farm028', 'farm029', 'farm030', 'farm031', 'farm032', 'farm033', 'farm041', 'farm042', 'farm043', 'farm044', 'farm045', 'farm046', 'farm047', 'farm048', 'farm049', 'farm050', 'farm051', 'farm052']
.
With itertools.chain() :
# second code
from itertools import chain
import re
ncitems = 'farm011 - farm018, farm020, farm022 - farm033, farm041 - farm052'
print 'ncitems :\n',ncitems,'\n\n'
pat = re.compile("(\w+)(?<!\d)(\d+)(?:[ -]+(\w+)(?<!\d)(\d+))* *(?:,|\Z)")
gen = ( ("%s%03d"%(w1,i) for i in range(int(s),int(e)+1)) if w2
else ("%s%s"%(w1,s),)
for w1,s,w2,e in pat.findall(ncitems) )
items = list(chain(*gen))
print 'items :\n',items
.
Note that if elements are like this one : far24idi2rm011 , all these codes still run correctly.
.
EDIT
I would write the Rumple Stiltskin's code as follows:
import re
inp = "farm011 - farm018, farm020, farm022 - farm033, farm041 - farm052"
range_re = re.compile("farm(\d+) - farm(\d+)")
op_list = []
for result in (range_re.match(i.strip()) for i in inp.split(",")):
if result:
start,end = map(int,result.groups())
for j in range(start, end + 1):
op_list.append("farm%03d" % j)
else:
op_list.append(i)
print op_list
.
EDIT 2
In fact, I wouldn't write the Rumple Stiltskin's code. My opinion is that it's a bad way to do: first a split(",") , then a search with a regex. An appropriate regex can match directly what is needed, so why going through dilatory instructions ?
If readability is the aim, and it's a good aim according to me, I think this code is the simplest and more readable:
import re
ncitems = 'farm011 - farm018, farm020, farm022 - farm033, farm041 - farm052'
print 'ncitems :\n', ncitems
pat = re.compile("(\w+)(?<!\d)(\d+)(?:[ -]+(\w+)(?<!\d)(\d+))* *(?:,|\Z)")
items = []
for w1,s,w2,e in pat.findall(ncitems):
if w2:
items.extend("%s%03d"%(w1,i) for i in xrange(int(s),int(e)+1))
else:
items.append("%s%s"%(w1,s))
print '\nitems :\n',items