【问题标题】:Counting occurrences of Regex Matches in Python计算 Python 中正则表达式匹配的出现次数
【发布时间】:2021-01-23 02:17:39
【问题描述】:

我有一个日志检查器,它使用正则表达式从日志文件中的行中查找 IP。 我想找到这些行,并计算通过 IP 匹配的相同行的总出现次数

目标是根据事件的 IP 从事件中生成统计信息。 示例:

WARNING - 192.168.1.1 TIMING OUT    
WARNING - 192.168.1.5 TIMING OUT    
WARNING - 192.168.1.1 TIMING OUT    
WARNING - 192.168.1.5 TIMING OUT    
WARNING - 192.168.1.1 TIMING OUT    
WARNING - 10.1.1.1 TIMING OUT    
WARNING - 10.72.3.1 TIMING OUT    

192.168.1.1 - 3 EVENTS    
192.168.1.5 - 2 EVENTS    
10.1.1.1 - 1 EVENT    
10.72.3.1 - 1 EVENT

如此等等。我是 python 新手,所以我仍在学习最适合此目的的方法。到目前为止,我打开了日志文件,使用正则表达式模式执行 for 循环以查找每一行中的 IP,但从那里我有点迷失了。干杯。

【问题讨论】:

  • 只需使用字典,键为 IP 地址,每次遇到每个 IP 地址时递增值。
  • @Nick 欢呼。您能否澄清一下 - 使用字典我会明确定义我需要记录的每个 IP 地址吗?通过日志,我可能会查看 50-100 多个不同的地址。
  • 不,您可以使用变量作为键,并使用defaultdict 来避免担心未定义的索引,例如rextester.com/CPP47999

标签: python regex sorting logging counting


【解决方案1】:

以下是我在https://stackoverflow.com/a/64220148/6632736 的答案的修改版本。

假设日志在一个文件中,逐行读取。

#!/usr/bin/python
import os
import re

def increment(ips: dict, line: str):
    match = re.match(r'^.+?\s+-\s+(?P<ip>\d{1,3}(\.\d{1,3}){3})\s.*$', line)
    if match:
        ip = match.group('ip')
        if not ip in ips:
            ips[ip] = 0
        ips[ip] += 1

def parse_log_file(log: str) -> dict:
    ips = dict()
    with open(log, 'r') as file:
        for line in file:
            increment(ips, line)
    return ips

# log is the path to the log file:
for key, value in parse_log_file(log).items():
    print(key, ":", value)

【讨论】:

【解决方案2】:

您可以在此处使用re.findall 来捕获所有 IP 地址事件,然后使用映射来统计出现次数:

inp = """WARNING - 192.168.1.1 TIMING OUT    
WARNING - 192.168.1.5 TIMING OUT    
WARNING - 192.168.1.1 TIMING OUT    
WARNING - 192.168.1.5 TIMING OUT    
WARNING - 192.168.1.1 TIMING OUT    
WARNING - 10.1.1.1 TIMING OUT    
WARNING - 10.72.3.1 TIMING OUT"""

matches = re.findall(r'\bWARNING - (\b\d+\.\d+\.\d+\.\d+\b)', inp)
d = {}

for elem in matches:
    try:
        val = d.get(elem) or 0
        d[elem] = val + 1
    except KeyError:
        d[elem] = d[elem]

print(d)

打印出来:

{'10.1.1.1': 1, '192.168.1.5': 2, '10.72.3.1': 1, '192.168.1.1': 3}

【讨论】:

  • @VishalSingh 抱歉,脚本中有错字,请重试。我已经给你投票了。
  • 您没有使用Counter 执行此操作是否有特定原因?
  • 我的回答假设您已经在 Python 字符串中拥有整个日志文本。另一方面,如果您是逐行读取日志文件,那么您可能会从一张地图开始并以这种方式计数。
  • from collections import Counter d = Counter(matches)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2012-02-24
  • 2015-04-10
  • 2016-03-18
  • 1970-01-01
  • 2015-04-17
相关资源
最近更新 更多