逐行读取文本文件,并在Python中匹配特定模式的地方存储变量

时间:2018-08-29 19:33:23

标签: python regex python-3.6 readline findall

我们有一个大的日志文件,其中包含以下两行:

00 LOG     |   Cycles Run:  120001
00 LOG     ! Virtual: Max> ?????????? bytes (?.???? gb), Current> 640733184 bytes (?.???? gb).

00 LOG     ! Virtual: Max> 1082470400 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

00 LOG     ! Actual: Max> ????????? bytes (?.???? gb), Current> 472154112 bytes (?.???? gb).

00 LOG     ! Actual: Max> 861736960 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

由于日志文件很大,我们希望逐行读取(而不是一次读取缓冲区中的整个文本),匹配特定的模式集并在单独的变量中选择值。

例如

00 LOG     |   Cycles Run:  120001

我们要选择120001并存储在变量cycle中。

另一方面,我们解析这些行:

00 LOG     ! Virtual: Max> ?????????? bytes (?.???? gb), Current> 640733184 bytes (?.???? gb).

00 LOG     ! Virtual: Max> 1082470400 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

00 LOG     ! Actual: Max> ????????? bytes (?.???? gb), Current> 472154112 bytes (?.???? gb).

00 LOG     ! Actual: Max> 861736960 bytes (?.???? gb), Current> ????????? bytes (?.???? gb).

标有?的字符可以是任何数字。

我们要存储如下所示的可变商品:

  

640733184 in var virtual_cur

     

1082470400 in var virtual_max

     

472154112 in var actual_cur

     

861736960 in var actual_max

Python 3.6中写了一个代码段,但它正在打印空列表:

import re

filename = "test.txt"
with open(filename) as fp:  
   line = fp.readline()
   while line:
       cycle_num = re.findall(r'00 LOG     |   Cycles Run:  (.*?)',line,re.DOTALL)
       line = fp.readline()

print (cycle_num[0])
  

注意:我想选择单独变量中的每个值并使用它   稍后的。需要一一设置5种模式,如果匹配则选择值   任何特定的模式,然后将其放在各自的变量中。

不确定第二个模式的通配符是否匹配。

请为我们建议一种有效的方法。

3 个答案:

答案 0 :(得分:2)

使用正则表达式

(?:(?:Cycles Run:[ \t]+)|(?:Current>[ \t]+))(\d+)

Demo

您可以按照以下方式进行操作:

import re
pat=re.compile(r'(?:(?:Cycles Run:[ \t]+)|(?:Current>[ \t]+))(\d+)')
with open('test.txt','r') as f:   
    for line_num, line in enumerate(f):
        m=pat.search(line)
        if m:
            print(line_num, m.group(0))

答案 1 :(得分:1)

您可以在此处使用两个后面的替代符号:

(?<=Cycles Run:  )\d+|(?<= Current>  )\d+

正则表达式演示https://github.com/awslabs/serverless-application-model/blob/master/examples/2016-10-31/lambda_edge/template.yaml]


Python示例:

import re
text = '''
00 LOG     |   Cycles Run:  120001
00 LOG     !   Virtual: Max> 1082470400 bytes (1.0081 gb), Current>  640733184 bytes (0.5967 gb)
'''

pattern = re.compile(r'(?<=Cycles Run:  )\d+|(?<= Current>  )\d+')
matches = re.findall(pattern,text)
num_cycle = matches[0]
current = matches[1]

print(num_cycle,current)

打印:

120001 640733184

在循环中重复该过程时,建议仅在循环之前使用re.compile来编译模式。

答案 2 :(得分:0)

我们在这里搜索一些标识符(例如cycles并应用其他正则表达式)

import re
with open('test.txt','r') as f:
    for line in f:
        if re.search(r'Cycles',line):
            m=re.findall(r'\d+$',line)
        else:
            m=re.findall(r'Current>  (\d+)',line)
        print(m)