我正在尝试做一些我认为简单(可能是)的事情,但是我正在撞墙。我有一个包含文档编号的字符串。在大多数情况下,格式为 ###### - # - ### 但是在某些情况下,应该是单个数字,有多个单个数字分隔用逗号表示(即 ###### - #,#,# - ### )。由逗号分隔的单个数字的位数是可变的。以下是一个例子:
对于下面的字符串:
('030421-1,2-001 & 030421-1-002,030421-1,2,3-002, 030421-1-003')
我需要回复:
['030421-1-001', '030421-2-001' '030421-1-002', '030421-1-002', '030421-2-002', '030421-3-002' '030421-1-003']
我只返回与 ###### - # - ### 模式匹配的字符串:
import re
p = re.compile('\d{6}-\d{1}-\d{3}')
m = p.findall('030421-1,2-001 & 030421-1-002,030421-1,2,3-002, 030421-1-003')
print m
提前感谢您的帮助!
马特
答案 0 :(得分:2)
也许是这样的:
>>> import re
>>> s = '030421-1,2-001 & 030421-1-002,030421-1,2,3-002, 030421-1-003'
>>> it = re.finditer(r'(\b\d{6}-)(\d(?:,\d)*)(-\d{3})\b', s)
>>> for m in it:
a, b, c = m.groups()
for x in b.split(','):
print a + x + c
...
030421-1-001
030421-2-001
030421-1-002
030421-1-002
030421-2-002
030421-3-002
030421-1-003
或使用列表理解
>>> [a+x+c for a, b, c in (m.groups() for m in it) for x in b.split(',')]
['030421-1-001', '030421-2-001', '030421-1-002', '030421-1-002', '030421-2-002', '030421-3-002', '030421-1-003']
答案 1 :(得分:0)
使用'\d{6}-\d(,\d)*-\d{3}'
。
*
表示"尽可能多(包括0)"。
它应用于上一个元素,此处为'(,\d)'
。
答案 2 :(得分:0)
我不会使用单个正则表达式来尝试解析它。由于它本质上是一个字符串列表,您可能会发现更换"&"在字符串中全局使用逗号,然后使用split()将元素放入列表中。
执行列表循环将允许您编写单个函数来解析并修复字符串,然后您可以将其推送到新列表并显示您的字符串。
replace(string, '&', ',')
initialList = string.split(',')
for item in initialList:
newItem = myfunction(item)
newList.append(newItem)
newstring = newlist(join(','))
答案 3 :(得分:0)
(\d{6}-)((?:\d,?)+)(-\d{3})
我们采取3个捕获组。我们以简单的方式匹配第一部分和最后部分。中心部分可选地重复并且可选地包含“'”。然而,正则表达式只匹配最后一个,因此?:
根本不会存储它。剩下的是以下结果:
>>> p = re.compile('(\d{6}-)((?:\d,?)+)(-\d{3})')
>>> m = p.findall('030421-1,2-001 & 030421-1-002,030421-1,2,3-002, 030421-1-003')
>>> m
[('030421-', '1,2', '-001'), ('030421-', '1', '-002'), ('030421-', '1,2,3', '-002'), ('030421-', '1', '-003')]
你必须手动处理第二个术语以将它们拆分并加入它们,但列表理解应该能够做到这一点。