python中的文本解析问题

python中的文本解析问题,python,file,parsing,text,Python,File,Parsing,Text,我试图找出如何从这个文本文件中获取每个AP行上的客户端数量,这对于那些有“Num of clients”(在下一行)关联的客户端来说似乎很好,但是您可以看到,如果没有客户端关联到它,它就不会打印Num个客户端 我无法理解检查下一行以查看是否存在“num of clients”,然后返回到当前行的逻辑。如果存在,则应转到下一行并获取客户机号码。如果没有“num of clients”行,我将尝试将客户端设置为0 我有一个包含以下内容的文件: for line in file: if

我试图找出如何从这个文本文件中获取每个AP行上的客户端数量,这对于那些有“Num of clients”(在下一行)关联的客户端来说似乎很好,但是您可以看到,如果没有客户端关联到它,它就不会打印Num个客户端

我无法理解检查下一行以查看是否存在“num of clients”,然后返回到当前行的逻辑。如果存在,则应转到下一行并获取客户机号码。如果没有“num of clients”行,我将尝试将客户端设置为0

我有一个包含以下内容的文件:

for line in file:   
    if "AP" in line:
        ap = re.search('AP[0-99]+', line)
        print ap.group(0),
    elif "Num of clients" in line:  
        clients = re.search('[0-99]+', line)
        print '- ' + clients.group(0)
AP1 AP2 - 8
AP3 - 21
AP4 AP5 - 2
AP6 - 5
AP7 - 2
AP8 - 5
AP9 - 5
wireless-detail.txt

RUDY>show wireless ap detail on AP1 | include clients
RUDY>show wireless ap detail on AP2 | include clients
 Num of clients       : 8  
RUDY>show wireless ap detail on AP3 | include clients
 Num of clients       : 21
RUDY>show wireless ap detail on AP4 | include clients
RUDY>show wireless ap detail on AP5 | include clients
 Num of clients       : 2
现在我有以下几点:

for line in file:   
    if "AP" in line:
        ap = re.search('AP[0-99]+', line)
        print ap.group(0),
    elif "Num of clients" in line:  
        clients = re.search('[0-99]+', line)
        print '- ' + clients.group(0)
AP1 AP2 - 8
AP3 - 21
AP4 AP5 - 2
AP6 - 5
AP7 - 2
AP8 - 5
AP9 - 5
它当前打印以下内容:

for line in file:   
    if "AP" in line:
        ap = re.search('AP[0-99]+', line)
        print ap.group(0),
    elif "Num of clients" in line:  
        clients = re.search('[0-99]+', line)
        print '- ' + clients.group(0)
AP1 AP2 - 8
AP3 - 21
AP4 AP5 - 2
AP6 - 5
AP7 - 2
AP8 - 5
AP9 - 5
让它检查下一行以查看AP是否应设置为0客户端的最佳方法是什么

编辑:FWIW-我正在尝试file.next()读取下一行,这似乎可行,但我无法返回到上一行:/


编辑2:我希望我能投票超过你们所有人。谢谢大家!令人难以置信的是,有这么多的方法可以做到这一点,而我却无法找出其中的一种

你想得太多了。不要使用正则表达式。他们很慢,有车,你们的模式很明确。做一些像

for line in file:
    if "AP" in line:
        i = line.find('AP')
        splitLine = line[i+2:].split('|')
        val = splitLine[0]
        print val,
    elif "Num of clients" in line:
        splitLine = line.split(':')
        num = splitLine[1]
        print '- ' + num

你想得太多了。不要使用正则表达式。他们很慢,有车,你们的模式很明确。做一些像

for line in file:
    if "AP" in line:
        i = line.find('AP')
        splitLine = line[i+2:].split('|')
        val = splitLine[0]
        print val,
    elif "Num of clients" in line:
        splitLine = line.split(':')
        num = splitLine[1]
        print '- ' + num

如果要使用RE,可以这样做。变量用于确定是否需要计数行。如果计数行可用,则使用它,否则将其设置为
-0

need_count = 0
for line in file:   
    if "AP" in line:
        if need_count:
           print '- 0'
        ap = re.search('AP[0-99]+', line)
        print ap.group(0)
        need_count = 1
    elif "Num of clients" in line:  
        clients = re.search('[0-99]+', line)
        print '- ' + clients.group(0)
        need_count = 0

如果要使用RE,可以这样做。变量用于确定是否需要计数行。如果计数行可用,则使用它,否则将其设置为
-0

need_count = 0
for line in file:   
    if "AP" in line:
        if need_count:
           print '- 0'
        ap = re.search('AP[0-99]+', line)
        print ap.group(0)
        need_count = 1
    elif "Num of clients" in line:  
        clients = re.search('[0-99]+', line)
        print '- ' + clients.group(0)
        need_count = 0

这里有一个使用正则表达式的简短方法。请注意re.MULTILINE标志

s='''RUDY>show wireless ap detail on AP1 | include clients
RUDY>show wireless ap detail on AP2 | include clients
 Num of clients       : 8  
RUDY>show wireless ap detail on AP3 | include clients
 Num of clients       : 21
RUDY>show wireless ap detail on AP4 | include clients
RUDY>show wireless ap detail on AP5 | include clients
 Num of clients       : 2'''
import re
print re.findall(r'(AP\d) \| include clients(?:$\n Num of clients {7}: (\d))?',s,flags=re.M)
(?:$\n客户端数{7}:(\d))?
构成一个非捕获组,并与?最后,它是可选的。如果它执行捕获,则第二个匹配组将为空,与1和4相同

“{7}”
表示7个空格

打印此文件:

  [('AP1', ''), ('AP2', '8'), ('AP3', '2'), ('AP4', ''), ('AP5', '2')]

这里有一个使用正则表达式的简短方法。请注意re.MULTILINE标志

s='''RUDY>show wireless ap detail on AP1 | include clients
RUDY>show wireless ap detail on AP2 | include clients
 Num of clients       : 8  
RUDY>show wireless ap detail on AP3 | include clients
 Num of clients       : 21
RUDY>show wireless ap detail on AP4 | include clients
RUDY>show wireless ap detail on AP5 | include clients
 Num of clients       : 2'''
import re
print re.findall(r'(AP\d) \| include clients(?:$\n Num of clients {7}: (\d))?',s,flags=re.M)
(?:$\n客户端数{7}:(\d))?
构成一个非捕获组,并与?最后,它是可选的。如果它执行捕获,则第二个匹配组将为空,与1和4相同

“{7}”
表示7个空格

打印此文件:

  [('AP1', ''), ('AP2', '8'), ('AP3', '2'), ('AP4', ''), ('AP5', '2')]

如果希望数据采用更结构化的格式(如字典),可以尝试以下方法:

with open('wireless-detail.txt', 'r') as fp:
    access_points = {}
    ap = None
    for line in fp:
        if 'AP' in line:
            ap = line[line.find('AP'):line.find('|')].strip()
            access_points[ap] = 0
        elif "Num of clients" in line:
            access_points[ap] = int(line.split(':')[1].strip())

print access_points
返回:

{'AP2': 8, 'AP3': 21, 'AP1': 0, 'AP4': 0, 'AP5': 2}

我同意以前的解决方案,即
re
对于这类任务来说是一个不必要的复杂问题,因为您的文件可以可靠地输出。这种方法的一个好处是,您还可以获得关于没有连接用户的已知访问点的信息,例如AP1=0(也是int()形式!)

如果您希望数据采用更结构化的格式,如字典,您可以尝试以下方法:

with open('wireless-detail.txt', 'r') as fp:
    access_points = {}
    ap = None
    for line in fp:
        if 'AP' in line:
            ap = line[line.find('AP'):line.find('|')].strip()
            access_points[ap] = 0
        elif "Num of clients" in line:
            access_points[ap] = int(line.split(':')[1].strip())

print access_points
返回:

{'AP2': 8, 'AP3': 21, 'AP1': 0, 'AP4': 0, 'AP5': 2}

我同意以前的解决方案,即
re
对于这类任务来说是一个不必要的复杂问题,因为您的文件可以可靠地输出。这种方法的一个好处是,您还可以获得关于没有连接用户的已知访问点的信息,例如,AP1=0(也是int()形式!)

这可能有些过分,但接下来

我制作了一个库,其中包含一些类似的功能,这些功能经常派上用场:

def fileLineGroups (f, count=2, truncate=True):
    lines = []
    for line in f:
        lines.append(line)
        if len(lines) == count:
            yield lines
            lines = lines[1:]
    if not truncate:
        if lines:
            yield lines
这将在打开的文件句柄的行上迭代,生成行组。它默认为2个组,因此它将返回[line1,line2],然后返回[line2,line3],等等。如果启用truncate,则如果最后一个组中没有计数行,它将不会返回最后一个组。这使您可以在fileLineGroups(f)中为a、b执行
之类的操作,如果最后一个是奇数,则不会出错

现在您可以执行以下操作:

import re
def getAPClientCounts (filepath):
    with open(filename) as f:
        for line1, line2 in py.fileLineGroups(f):
            match1 = re.search('AP\d*', line1)
            if match1:
                match2 = re.search('Num of clients.*: (\d*)', line2)
                if match2:
                    yield match1.group(), match2.groups()[0]

for ap, count in getAPClientCounts('wireless-detail.txt'):
    print 'AP with name %s has %s clients' % (ap, count)

AP with name AP2 has 8 clients
AP with name AP3 has 21 clients
AP with name AP5 has 2 clients

这可能有点过头了,但接下来

我制作了一个库,其中包含一些类似的功能,这些功能经常派上用场:

def fileLineGroups (f, count=2, truncate=True):
    lines = []
    for line in f:
        lines.append(line)
        if len(lines) == count:
            yield lines
            lines = lines[1:]
    if not truncate:
        if lines:
            yield lines
这将在打开的文件句柄的行上迭代,生成行组。它默认为2个组,因此它将返回[line1,line2],然后返回[line2,line3],等等。如果启用truncate,则如果最后一个组中没有计数行,它将不会返回最后一个组。这使您可以在fileLineGroups(f)
中为a、b执行
之类的操作,如果最后一个是奇数,则不会出错

现在您可以执行以下操作:

import re
def getAPClientCounts (filepath):
    with open(filename) as f:
        for line1, line2 in py.fileLineGroups(f):
            match1 = re.search('AP\d*', line1)
            if match1:
                match2 = re.search('Num of clients.*: (\d*)', line2)
                if match2:
                    yield match1.group(), match2.groups()[0]

for ap, count in getAPClientCounts('wireless-detail.txt'):
    print 'AP with name %s has %s clients' % (ap, count)

AP with name AP2 has 8 clients
AP with name AP3 has 21 clients
AP with name AP5 has 2 clients

我建议您使用无线控制器平台可能具有的编程接口之一来查询无线控制器平台,例如SNMP、XML-RPC/SOAP。然后你可以将关联计数绘制成图形。嗨,Matt,我最初试图通过SNMP进行此操作,但关联计数的查询是通过控制器列出的,我没有将IP分配给AP:(我建议您使用无线控制器平台可能具有的编程接口之一查询无线控制器平台,例如SNMP、XML-RPC/SOAP。然后您可以绘制关联计数。嗨,Matt,我最初尝试通过SNMP进行此操作,但关联计数的查询是通过控制器列出的,我没有为AP分配IP。)(此解决方案产生明显不可读的输出,使用关键字作为变量名,可重用性差(打印后无法使用提取的数据)。:(此解决方案产生明显不可读的输出,使用关键字作为变量名,可重用性差(打印后无法使用提取的数据)。:(