这里有一个关于正则表达式的快速问题。我有一个文件(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个。任何想法我怎么能正确地做到这一点?
答案 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