使用正则表达式从日志文件中提取数字字段

时间:2015-01-18 23:04:30

标签: python regex

我有一个输出日志文件:

Time = 1

smoothSolver:  Solving for Ux, Initial residual = 0.230812, Final residual = 0.0134171, No Iterations 2
smoothSolver:  Solving for Uy, Initial residual = 0.283614, Final residual = 0.0158797, No Iterations 3
smoothSolver:  Solving for Uz, Initial residual = 0.190444, Final residual = 0.016567, No Iterations 2
GAMG:  Solving for p, Initial residual = 0.0850116, Final residual = 0.00375608, No Iterations 3
time step continuity errors : sum local = 0.00999678, global = 0.00142109, cumulative = 0.00142109
smoothSolver:  Solving for omega, Initial residual = 0.00267604, Final residual = 0.000166675, No Iterations 3
bounding omega, min: -26.6597 max: 18468.7 average: 219.43
smoothSolver:  Solving for k, Initial residual = 1, Final residual = 0.0862096, No Iterations 2
ExecutionTime = 4.84 s  ClockTime = 5 s

我需要使用Python的正则表达式提取累积= 0.00142109(在about输出的第5行)。更确切地说,我只需要提取对应于累积的值0.00142109并写入另一个文件。

目前,这就是我所拥有的:

contCumulative_0_out = open('contCumulative_0', 'w+')

with open(logFile, 'r') as logfile_read:
    for line in logfile_read:
        line = line.rstrip()
        if re.findall('cumulative = ([+-]?\d+)(?:\.\d+)?(?:[eE][+-]?\d+)?', line):
            print line
            contCumulative_0_out.write(line)

但是,上面代码的输出是:

time step continuity errors : sum local = 0.00999678, global = 0.00142109, cumulative = 0.00142109

我基本上得到了与累积

匹配的整行

请告诉我如何仅提取与累积相对应的值。

2 个答案:

答案 0 :(得分:0)

那是因为re.findall() returns you a list of strings而不是re.search()会返回MatchObject。 在任何情况下,您都会从re.find/search()来电中丢弃该返回值,然后您的代码只使用line

# Wrong
if re.findall(<regex>, line):
    print line
    contCumulative_0_out.write(line)

# Right
mat = re.search(<regex>, line) # but your regex needs changing, see below
if mat:
    cumvalue = mat.groups()
    print cumvalue
    contCumulative_0_out.write(cumvalue)
    #break # if you know you only have at most one match per file

然而,正如@Andrew_Lvov指出的那样,你的正则表达式太复杂了,并没有强制用数字​​开头。所以现在你需要解决这个问题。安德鲁的正则表达式更快更好(我们知道数字不会格式错误,我们无法获取具有多个句点的内容,例如IP地址)。

(顺便说一下,为了提高效率,如果你保证每个文件最多有一个'累积'行的实例,你在处理你的匹配后没有理由不从for循环break。{为了提高效率,line = line.rstrip()是不必要的。)

无论如何,浏览一下有关match,search和findall / finditer之间差异的文档。必须知道哪个是哪个。模式匹配的fns及其变体在几乎所有语言中都是一种痛苦。或者在Python shell中键入help(re)

答案 1 :(得分:0)

如果数字是您指定的格式,我会使用更简单的正则表达式模式:

for line in logfile_read:
    res = re.search(r'cumulative = ((\d|.)+)', line)
    if res:
        contCumulative_0_out.write(res.group(1))

否则,只需使用您的模式,但使用re.match并编写res.group(n)的walue,其中res是resulf或re.match,n是正则表达式exp中的子表达式数括在'('和')'。

相关问题