Python正则表达式,如何从1个字符串中捕获多个规则

时间:2014-04-09 21:19:07

标签: python regex

这里有一个关于正则表达式的快速问题。我有一个文件(testlog-date.log),其中包含这样的行

# 2014-04-09 16:43:15,136|PID: 1371|INFO|Test.Controller.Root|Finished processing request        in   0.003355s for https://website/heartbeat

我正在寻找使用正则表达式捕获PID和时间。到目前为止我有这个

import re

file_handler = open("testlog-20140409.log", "r")
for line in file_handler:
    var1 = re.findall(r'(\d+.\d+)s', line)
    print var1
file_handler.close()

所以我能够打印所有的处理时间。问题是如何捕获PID(以及可能的其他信息到我的变量var1?我试过这样做

var1 = re.findall(r'PID: (\d+) (\d+.\d+)s', line) 

打印出空结构。

非常感谢谢谢!

跟进:      我的文件非常大。我正在考虑将所有数据存储到一个结构中,并按处理时间对它们进行排序,然后打印出前20个。任何想法我怎么能正确地做到这一点?

3 个答案:

答案 0 :(得分:1)

您应该在.*?PID部分之间添加time(任何字符的非贪婪匹配):

>>> import re
>>> s = "# 2014-04-09 16:43:15,136|PID: 1371|INFO|Test.Controller.Root|Finished processing request        in   0.003355s for https://website/heartbeat"
>>> re.findall(r'PID: (\d+).*?(\d+.\d+)s', s)
[('1371', '0.003355')]

有关更通用的方法,请参阅@ shaktimaan的回答。

答案 1 :(得分:1)

使用正则表达式(.*)\|(PID: .*)\|(.*)\|(.*)\|(.*)。正则表达式模式中的每个括号表示一个单独的组。

In [125]: text = '2014-04-09 16:43:15,136|PID: 1371|INFO|Test.Controller.Root|Finished processing request        in   0.003355s for https://website/heartbeat'
In [126]: pattern = re.compile(r'(.*)\|(PID: .*)\|(.*)\|(.*)\|(.*)')
In [127]: results = re.findall(pattern, text)
In [128]: results
Out[128]:
[('2014-04-09 16:43:15,136',
  'PID: 1371,
  'INFO',
  'Test.Controller.Root',
  'Finished processing request        in   0.003355s for https://website/heartbeat')]

所以现在你有一个元组,每个元素属于你的每个组(时间戳,PID,例程,日志级别和日志消息。

编辑

对于大文件,正则表达式非常耗时。你的日志行有' |'作为分隔符。您可以使用它们来分割线。

all_lines = []
for line in file:
    all_lines.append(line.split('|'))

这将数据存储为列表列表:

[['2014-04-09 16:43:15,136','PID: 1371','INFO','Test.Controller.Root','Finished processing request        in   0.003355s for https://website/heartbeat'],
...,
...]

要对all_lines进行排序,您可以使用sorted()函数并将每个子列表的第一个字段作为比较器传递。

sorted_lines = sorted(all_lines, key=lambda x: x[0])

答案 2 :(得分:0)

您可以使用

(?P<name>...)

与常规括号类似,但可以通过符号组名称访问组匹配的子字符串。

它使阅读代码更容易..

另外,对于大文件,最好先编译正则表达式。

https://docs.python.org/2/library/re.html

案例中的例子:

def searchData(line):
    pattern=re.compile(r"^#\s+(?P<date>[^\|]+)\|PID:\s*(?P<pid>[0-9]+)\|.*")

    try:
        result=pattern.search(line)
        if not result:
            raise ValueError

    except ValueError:

        #print "Nothing found in \"%s\"" % line.strip("\n")
        return None

    else:
        date=result.group('date')
        pid=result.group('pid')
        return date,pid