m = re.match(r'(\d+)(?:-(\d+))?$', string)
start = m.group(1)
end = m.group(2) or start
return list(range(int(start, 10), int(end, 10) + 1))
现在,它能够以下列格式处理字符串并将它们转换为列表...
'0-6'导致[0,1,2,3,4,5,6]
'7'导致[7]
无论如何,我可以更改符号以便能够处理以下格式的字符串...
'1 2 3 4 5'结果为[1,2,3,4,5]
答案 0 :(得分:6)
正则表达并不是生活中的全部。在这种情况下,没有理由使用正则表达式。试试这个,它的速度是示例数据to_num_list
上Shawn Chin的'0-6 2 3-6'
的两倍(对于我尝试过的所有数据,它的速度在1.9到4.5倍之间):< / p>
def included_numbers(s):
out = []
for chunk in s.split():
if '-' in chunk:
f, t = chunk.split('-')
out.extend(range(int(f), int(t)+1))
else:
out.append(int(chunk))
return out
答案 1 :(得分:3)
我会坚持使用相同的符号,然后使用re.findall()
来获得所有匹配。实施例
import re
def to_num_list(instr):
out = []
for m in re.finditer(r'(\d+)(?:-(\d+))?', instr):
if m.group(2) == None:
out.append(int(m.group(1)))
else:
start = int(m.group(1))
end = int(m.group(2))
out.extend(xrange(start, end + 1))
return out
这将使您能够处理诸如"1 2 3 10-15"
之类的输入。用法示例:
>>> to_num_list("0-6")
[0, 1, 2, 3, 4, 5, 6]
>>> to_num_list("10")
[10]
>>> to_num_list("1 3 5")
[1, 3, 5]
>>> to_num_list("1 3 5 7-10 12-13")
[1, 3, 5, 7, 8, 9, 10, 12, 13]
并跳过错误的输入(可能不一定是你想要的):
>>> to_num_list("hello world 1 2 3")
[1, 2, 3]
>>> to_num_list("")
[]
>>> to_num_list("1 hello 2 world 3")
[1, 2, 3]
>>> to_num_list("1hello2")
[1, 2]
答案 2 :(得分:1)
m = re.match(r'(?:(\d+)(?:-(\d+))|(?:(\d+)(?:\s+|$))+)?$', string)
然后,查看第3组的捕获。
答案 3 :(得分:0)
两种输入格式可以由非贪婪的正则表达式匹配(在*之后用?量词指定):
m = re.match(r'^(\d+)[0-9\-\s]*?(\d+)?$', string)
总是将第一个数字和最后一个数字分别提取到m.group(1)和m.group(2)中,或者如果只有一个数字,它将在m.group(1)中匹配
请参阅python文档中的greedy vs non-greedy。
答案 4 :(得分:0)
如果您可以使用拆分,则可以简化正则表达式,并让拆分处理所有空格分隔的列表定义。
import re
def answer(string):
m = re.match(r'(\d+)-(\d+)$', string)
if m:
start = m.group(1)
end = m.group(2) or start
return list(range(int(start), int(end) + 1))
return map(int, string.split(' '))