【问题标题】:IP address/network parsing from text file using python使用python从文本文件中解析IP地址/网络
【发布时间】:2014-12-09 19:24:05
【问题描述】:

我有以下文本文件,在解析 IP 地址时需要一些帮助。

文本文件的格式为

abc 10.1.1.1/32   aabbcc
def 11.2.0.0/16   eeffgg
efg 0.0.0.0/0   ddeeff

换句话说,大量 IP 网络作为日志文件的一部分存在。输出应提供如下:

10.1.1.1/32
11.2.0.0/16
0.0.0.0/0

我有以下代码,但没有输出所需的信息

file = open(filename, 'r')
for eachline in file.readlines():
    ip_regex = re.findall(r'(?:\d{1,3}\.){3}\d{1,3}', eachline)
    print ip_regex

【问题讨论】:

  • 尝试描述每一行代码的作用,你会发现错误。也请参阅重新文档。
  • 好吧,你没有在你的正则表达式中包含任何内容来匹配最后的 /32 或类似的东西,所以它当然只会匹配 10.1.1.1 或类似的东西。
  • re.findall("\d+\.\d+\.\d+\.\d+\/\d+",file.read()),你也应该使用with来打开你的文件
  • 附带说明,这里没有理由使用readlines()file 已经是一个可迭代的行。你所做的只是浪费地强迫 Python 在你使用它之前读取和解析内存中的整个文件。
  • 另外说明,这些不是 IP 地址,而是 IP 网络,其中包含地址和位掩码。事实上,您现有的代码已经查找属于这些网络的 IP 地址……

标签: python regex ip


【解决方案1】:

首先,您的正则表达式甚至不会尝试捕获除了四个虚线数字之外的任何内容,因此它当然不会匹配任何其他内容,例如最后的 /32。如果您只是在末尾添加例如/\d{1,2},它会解决这个问题:

(?:\d{1,3}\.){3}\d{1,3}/\d{1,2}

Debuggex Demo


但是,如果您对正则表达式的理解不够好,无法理解,您可能不应该将正则表达式用作您永远无法调试或扩展的“魔法”。使用str 方法(如splitfind)会更冗长一些,但对于新手来说可能更容易理解:

for line in file:
    for part in line.split()
        try:
            address, network = part.split('/')
            a, b, c, d = address.split('.')
        except ValueError:
            pass # not in the right format
        else:
            # do something with part, or address and network, or whatever

附带说明一下,根据您实际处理这些事情的目的,您可能希望使用 ipaddress 模块(或 the backport on PyPI 用于 2.6-3.2)而不是字符串解析:

>>> import ipaddress
>>> s = '10.1.1.1/32'
>>> a = ipaddress.ip_network('10.1.1.1/32')

您可以将其与上述任何一种结合:

for line in file:
    for part in line.split():
        try:
            a = ipaddress.ip_network(part)
        except ValueError:
            pass # not the right format
        else:
            # do something with a and its nifty methods

【讨论】:

  • @abernert 链接到的这个网站 Debuggex,是我见过的最好的正则表达式网站。
  • @TehTris:是的,我很喜欢。但是请注意,一旦它们退出测试版,它们显然会开始对非 JS 正则表达式收费。他们已经开始对转换为纯英语的功能收费(然后他们禁用了……)。非常聪明;我不确定我是否可以回到……我曾经使用过的任何东西,我什至不记得了。 :)
  • ipaddress 不适用于“010.200.074.104”这样的地址。要解析这个,最好使用这样的单行: ".".join([str(int(x)) for x in ipv4_str.split(".")])
【解决方案2】:

在这种特殊情况下,正则表达式可能有点矫枉过正,您可以使用split

with open(filename) as f:
    ipList = [line.split()[1] for line in f]

这应该会产生一个字符串列表,即 IP 地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 2016-11-17
    • 2021-11-17
    • 2013-02-15
    • 2015-06-02
    • 1970-01-01
    相关资源
    最近更新 更多