使用正则表达式提取特定行下面一行的数字?

时间:2018-02-08 01:00:58

标签: python regex python-3.x

如果我在文本文件中有以下行:

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

然而,没有任何回报。

谢谢。

3 个答案:

答案 0 :(得分:2)

使用re.findallre.searchre.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模块中的dropwhileitertools函数:

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