【问题标题】:Python - List issues (multiple lists?)Python - 列表问题(多个列表?)
【发布时间】:2012-03-12 20:00:16
【问题描述】:

以下是我正在尝试编写的脚本的一部分。该脚本会打开我的 iptables 日志,日志中的每一行都包含以下示例中的详细信息。

#单行示例 #Mar 9 14:57:51 机器内核:[23780.638839] IPTABLES 拒绝 UDP:IN=p21p1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00 :00 SRC=10.100.1.4 DST=10.100.1.63 LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=10898 PROTO=UDP$ # 一次读取一行文件 对于 iptables_log.readlines() 中的行: #根据 4 个字母、2 个空格、最多 2 个数字、1 个空格来查找时间,然后是标准 10:10:10 时间格式 time = re.findall('(^\w{1,4}\s\s\d{1,2}\s\d\d:\d\d:\d\d)', 行) #mac 查找 mac = re.findall('MAC=(?:\w\w:\w\w:\w\w:\w\w\:\w\w:\w\w:\w\w:\w \w:\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)', 行) #源端口 src = re.findall('SRC=(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3 })\.(?:[\d]{1,3})', 行) #目的端口 dst = re.findall('DST=(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3 })\.(?:[\d]{1,3})', 行) #协议 proto = re.findall('PROTO=(?:\w{3,4})', line) #源端口 sourceport = re.findall('SPT=(?:\w{1,5})', 行) #destport destport = re.findall('DPT=(?:\w{1,5})', 行) 打印时间、mac、src、dst、proto、sourceport、destport 打印'================================================== ======'

我试图让脚本只打印我想要的项目,但是当它由脚本输出时,它看起来像这样,这似乎是一个列表。我希望它在没有 [] '' 的情况下打印。在网上看,似乎每个变量(时间、mac、src 等)本身都是一个列表。我不确定如何将它们结合起来。我已经看到了加入的参考,但不知道如何在这个例子中使用它。有人可以帮忙吗?

['3 月 9 日 14:57:51'] ['MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00'] ['SRC=10.100. 1.4'] ['DST=10.100.1.63'] ['PROTO=UDP'] ['SPT=137'] ['DPT=137']

【问题讨论】:

  • 你为什么不用一个正则表达式来做这个?

标签: python list


【解决方案1】:

re.findall 返回一个列表

def findall(pattern, string, flags=0):
    """Return a list of all non-overlapping matches in the string.

    If one or more groups are present in the pattern, return a
    list of groups; this will be a list of tuples if the pattern
    has more than one group.

    Empty matches are included in the result."""
    return _compile(pattern, flags).findall(string)

我会改用 re.search。

>>> import re
>>> st = '''Mar  9 14:57:51 machine kernel: [23780.638839] IPTABLES Denied UDP: IN=p21p1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00 SRC=10.100.1.4 DST=10.100.1.63 LEN=78 TOS=0x00 PREC=0x00 TTL=128 ID=10898 PROTO=UDP$'''
>>> x = re.search('(^\w{1,4}\s\s\d{1,2}\s\d\d:\d\d:\d\d)',st)
>>> x.group(0)
'Mar  9 14:57:51'

(来源 = http://docs.python.org/library/re.html

【讨论】:

  • re.search 返回 None 如果字符串中没有位置与模式匹配。所以,在访问MatchObject之前,你应该检查你的结果是否不是None
【解决方案2】:

为什么不直接打开你的清单呢?

>>> time = [0]
>>> [time] = time
>>> time
0

【讨论】:

  • 列表解包类似于元组解包:>>> tuple = (0, 1) >>> (x, y) = tuple >>> x 0 >>> y 1 元组解包更多使用(因为您经常从具有多个结果的函数/方法返回元组)。
【解决方案3】:

你可以这样做:

foo = re.findall(…)[0]

如果你只期望一个结果,对于任何 re.findall

【讨论】:

    【解决方案4】:

    re.findall 返回匹配列表。在您的情况下,您得到的列表只有一个值。如果总是这样,那么@x539 的答案将获得列表中的第一项。

    【讨论】:

      【解决方案5】:

      我建议对整行使用单个正则表达式,并使用命名组,例如:

      >>> r = re.compile(r'^(?P<date>\w{1,4}\s\d{1,2}\s\d\d\:\d\d\:\d\d) (?P<hostname>\w+) kernel: (\[[0-9]+.[0-9]+\]) IN=(?P<ifacein>[a-z0-9]*) OUT=(?P<ifaceout>[a-z0-9]*) MAC=(?P<mac>[a-f0-9:]+) SRC=(?P<src>[\w.:]+) DST=(?P<dst>[\w:.]+) LEN=(?P<len>[0-9]+) TOS=0x(?P<tos>[0-9a-f]+) PREC=0x(?P<prec>[0-9a-f]+) TTL=(?P<ttl>[0-9]+) ID=(?P<id>[0-9]+) PROTO=(?P<proto>[A-Z]+) SPT=(?P<spt>[0-9]+) DPT=(?P<dpt>[0-9]+) LEN=(?P<len2>[0-9]+)')
      >>> d = r.match(line).groupdict()
      >>> d['dst']
      '255.255.255.255'
      >>> d['proto']
      'UDP'
      >>> d['dpt']
      '17500'
      

      您还可以轻松地将其全部返回到包含所需字段的单个字符串中:

      >>> ' '.join([d[_] for _ in ("date", "mac", "src", "dst", "proto", "spt", "dpt")])
      'Mar 12 13:06:10 ff:ff:ff:ff:ff:ff:00:18:8b:da:86:37:08:00 192.168.0.221 255.255.255.255 UDP 17500 17500'
      

      【讨论】:

        猜你喜欢
        • 2023-02-14
        • 2011-12-16
        • 2020-09-29
        • 2012-03-11
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 2017-12-04
        • 2017-03-09
        相关资源
        最近更新 更多