我有一些这样的文字:
CustomerID:1111,
text1
CustomerID:2222,
text2
CustomerID:3333,
text3
CustomerID:4444,
text4
CustomerID:5555,
text5
每个文字都有多行。
我想在元组中存储每个ID的客户ID和文本(例如(1111, text1)
,(2222, text2)
等)。
首先,我使用下面的表达式:
re.findall('CustomerID:(\d+)(.*?)CustomerID:', rawtxt, re.DOTALL)
但是,我只获得(1111, text1)
,(3333, text3)
,(5555, text5)
.....
答案 0 :(得分:2)
re.findall(r'CustomerID:(\d+),\s*(.*?)\s*(?=CustomerID:|$)', rawtxt, re.DOTALL)
Findall仅返回groups
。使用lookahead
来停止non greedy
量词。它还建议使用r
或raw
模式来指定您的正则表达式。如果您不使用lookahead
,那么{下一场比赛的{1}}将被使用,因此下一场比赛将不会出现。必须使用不customerid
的{{1}}删除重置比赛
答案 1 :(得分:2)
实际上这里不需要正则表达式:
>>> with open('file') as f:
... rawtxt = [i.strip() for i in f if i != '\n']
...
>>> l = []
>>> for i in [rawtxt[i:i+2] for i in range(0, len(rawtxt), 2)]:
... l.append((i[0][11:-1], i[1]))
...
...
>>> l
[('1111', 'text1'), ('2222', 'text2'), ('3333', 'text3'), ('4444', 'text4'), ('5
555', 'text5')]
>>>
如果您需要1111
,2222
等,请使用l.append((int(i[0][11:-1]), i[1]))
代替l.append((i[0][11:-1], i[1]))
。
答案 2 :(得分:1)
假设:
>>> txt='''\
... CustomerID:1111,
...
... text1
...
... CustomerID:2222,
...
... text2
...
... CustomerID:3333,
...
... text3
...
... CustomerID:4444,
...
... text4
...
... CustomerID:5555,
...
... text5'''
你可以这样做:
>>> [re.findall(r'^(\d+),\s+(.+)', block) for block in txt.split('CustomerID:') if block]
[[('1111', 'text1')], [('2222', 'text2')], [('3333', 'text3')], [('4444', 'text4')], [('5555', 'text5')]]
如果是多行文字,您可以这样做:
>>> [re.findall(r'^(\d+),\s+([\s\S]+)', block) for block in txt.split('CustomerID:') if block]
[[('1111', 'text1\n\n')], [('2222', 'text2\n\n')], [('3333', 'text3\n\n')], [('4444', 'text4\n\n')], [('5555', 'text5')]]
答案 3 :(得分:1)
另一个简单的可能是 -
>>>re.findall(r'(\b\d+\b),\s*(\btext\d+\b)', rawtxt)
>>>[('1111', 'text1'), ('2222', 'text2'), ('3333', 'text3'), ('4444', 'text4'), ('5555', 'text5')]
编辑 -
如果需要(对于更糟糕的有序数据),请使用filter
filter(lambda x: len(x)>1,re.findall(r'(\b\d+\b),\s*(\btext\d+\b)', rawtxt))
查看演示 Live Demo
答案 4 :(得分:0)
re.findall不是最好的工具,因为正则表达式总是贪婪的,并且会尝试用文本吞噬所有后续的customerID。
为此实际创建的工具是re.split。括号捕获id号并过滤掉“CustomerID”。第二行以你想要的方式将标记拼接成元组:
toks = re.split(r'CustomerID:(\d{4}),\n', t)
zip(toks[1::2],toks[2::2])
编辑:zip()中的更正索引。校正后的样本输出:
[('1111', 'text1\n'),
('2222', 'text2\n'),
('3333', 'text3\n'),
('4444', 'text4\n'),
('5555', 'text5')]