Python - 使用可变重复子字符串解析字符串

时间:2014-12-30 18:30:01

标签: python regex string parsing substring

我正在尝试做一些我认为简单(可能是)的事情,但是我正在撞墙。我有一个包含文档编号的字符串。在大多数情况下,格式为 ###### - # - ### 但是在某些情况下,应该是单个数字,有多个单个数字分隔用逗号表示(即 ###### - #,#,# - ### )。由逗号分隔的单个数字的位数是可变的。以下是一个例子:

对于下面的字符串:

('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

提前感谢您的帮助!

马特

4 个答案:

答案 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')]

你必须手动处理第二个术语以将它们拆分并加入它们,但列表理解应该能够做到这一点。