[英]Python regex, how to capture multiple rules from 1 string
这里有一个关于正则表达式的快速问题。 我有一个文件(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个。任何想法我怎么能正确地做到这一点?
你应该把.*?
( 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的回答。
使用正则表达式(.*)\\|(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])
你可以用
(?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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.