如果我在文本文件中有以下行:
5 HIV serotype 2
3838 28282 4949
383 292 1012
10 SIV unknown serotype
3939 433 332 3222 122
3221 222 345 433 393 303
...我想从5 HIV血清型系下面提取数字,并且在10 SIV未知血清型系之上,我假设以下方法可行:
import re
with open('test.dat', 'r') as f:
line = line.strip()
if re.match('\d\s+HIV.*?(\d+)', line, re.MULTILINE):
print(re.match())
然而,没有任何回报。
谢谢。
答案 0 :(得分:2)
使用re.findall
和re.search
。 re.search
执行匹配HIV
部分的工作,其中re.findall
从匹配的部分中选择数字。
>>> import re
>>> s = '''5 HIV serotype 2
3838 28282 4949
383 292 1012
10 SIV unknown serotype
3939 433 332 3222 122
3221 222 345 433 393 303'''
>>> re.findall(r'\d+', re.search(r'(?s)\d+\s+HIV\s+(.*?)(?:\n\n|$)', s).group(1))
['2', '3838', '28282', '4949', '383', '292', '1012']
>>>
答案 1 :(得分:0)
如果您非常确定文件中存在这种格式,那么您就不需要正则表达式了。您只需使用takewhile
模块中的dropwhile
和itertools
函数:
In [131]: with open('test.txt') as f:
dropwhile(lambda x: x.startswith('5 HIV serotype'), f); next(f)
lines = takewhile(lambda x: not x.startswith('10 SIV unknown'), f)
print([j for l in lines for j in l.strip().split() if j])
.....:
['3838', '28282', '4949', '383', '292', '1012']
请注意,在处理大数据时,就内存和运行时而言,他是一种非常优化的方法。
答案 2 :(得分:0)
尝试以下代码(解释为注释):
with open("serotypes.txt", "r") as ff:
lines = ff.read().split("\n") # read file and split lines;
lines = list(map(lambda x: x.strip(), lines)) # trim each line;
lines.reverse() # reverse the list for pop to work below;
outlist = [] # empty output list;
try:
while True: # keep reading till exception occurs due to empty lines list
while True:
i = lines.pop() # ignore all till HIV Line;
if i.startswith("5 HIV serotype"):
outlist.append(i.split("5 HIV serotype")[1].strip()) # append last number of HIV Line;
break
while True:
i = lines.pop()
if i.startswith("10 SIV unknown serotype"): # if SIV line found, break out;
break
else:
outlist.extend(i.split()) # extend (not append) all lines till then to output list;
except:
pass
print(outlist)
文件输出' serotypes.txt'其中包含许多文本块:
['2', '3838', '28282', '4949', '383', '292', '1012', '2', '3838', '28282', '4949', '383', '292', '1012', '2', '3838', '28282', '4949', '383', '292', '1012', '2', '3838', '28282', '4949', '383', '292', '1012']