【问题标题】:Python - how to match specific words / digits from multiple lines in a text file and store them in separate listsPython - 如何匹配文本文件中多行的特定单词/数字并将它们存储在单独的列表中
【发布时间】:2015-02-20 21:24:22
【问题描述】:

我有一个 .txt 文件,它是这样的:

ip sla logging traps
ip sla 2553
ethernet jitter mpid 6553 domain Gravity vlan 2553 num-frames 100 interval 100
tag CSCO5839
frequency 300
ip sla schedule 2553 life forever start-time now
ip sla 3553
ethernet jitter mpid 7553 domain Gravity vlan 3553 num-frames 100 interval 100
tag CSCO5839
frequency 300
ip sla schedule 3553 life forever start-time now

我想要一种方法来匹配 ip sla / mpid / vlan 和标记并将它们的值存储到列表或向量中:

期望的输出:

ipsla[0]=2553ipsla[1]=3553
mpid[0]=6553mpid[1]=7553
vlan[0]=2553vlan[1]=3553
tag[0]=CSCO5839

现在,我刚开始学习 Python,我知道我必须解析文件的每一行,然后使用 re.match() 匹配所需的结果,然后将获得的结果存储在数组或列表中。

到目前为止我的代码很糟糕:

#!/usr/bin/env python

import re

myFile = open("regex.txt","r")

for line in myFile:
    if re.match("",line): #I should have a condition there but I got lost
        #now I have to store that variable in an array / or a list

到目前为止我的问题:
- 我应该使用什么表达才能找到我需要的东西?
- 那么,我怎样才能将这些值存储在同名的向量/列表中?例如:ipsla[0]ipsla[1]

如果可能的话,我也想要一些解释。

谢谢。

【问题讨论】:

标签: python regex string python-2.7


【解决方案1】:

解释您想要的正则表达式及其工作原理

以上所有答案都有效,但如果您想真正了解问题,我认为这可能是一个好方法。首先,您需要考虑要查找的内容。

对于前三个,您希望匹配name space digits 之类的模式。正则表达式是 name \d+ \d 表示数字字符,+ 表示一个或多个。

所以对于 ip sla 你会想要一个像这样的正则表达式:

ip sla \d+

但是你只对数字感兴趣,所以你可以使用括号将数字指定为它自己的组:

ip sla (\d+)

最后,在 python 中,反斜杠 (\) 用于转义它前面的字符,所以为了让 python 识别你的反斜杠,我们需要其中两个,所以在 python 代码中你会:

pattern = "ip sla (\\d+)"

如果你看一下the docs,re 模块有一个函数re.findall,它不需要将你的文件分成几行。

re.findall(pattern, string) 将返回与模式匹配的字符串列表,或者如果仅存在一个组(例如在我们的情况下,其中一组是 \d+),它将返回该组。

也就是说

re.findall("ip sla (\\d+)", fileText)

将返回作为您的 ip sla 值的数字列表(作为字符串)。

这也可以应用于 mpid 和 vlan。

但是,对于您想要匹配字母和数字的标签。在正则表达式中,这些被称为单词字符,为了匹配单词字符,我们可以使用\w。我们将再次使用+ 修饰符来匹配一个或多个单词字符。这给我们留下了

pattern = "tag (\\w+)"

策略:

1. Read file into string

2. Construct and execute regex searches for each pattern

3. Iterate through each list of results

4. Append each result to the correct array

代码:

import re

myFile = open("regex.txt","r")  # open file for reading
myFileData = myFile.read()      # read file into a string
myFile.close()                  # close file now that we're done

# create lists for each thing you're looking for
ipsla = []
mpid = []
vlan = []
tag = []

# finds a pattern like "ip sla <one or more digits 0-9>"
results = re.findall("ip sla (\\d+)", myFileData)
for result in results:
        # add the number (as an int) to your ipsla list
        ipsla.append(int(result))

# rinse & repeat :)
results = re.findall("mpid (\\d+)", myFileData)
for result in results:
        mpid.append(int(result))

results = re.findall("vlan (\\d+)", myFileData)
for result in results:
        vlan.append(int(result))

results = re.findall("tag (\\w+)", myFileData)
for result in results:
        if result not in tag:
                tag.append(result)

print ipsla
print mpid
print vlan
print tag

【讨论】:

  • 感谢您的解释。我现在都明白了。
【解决方案2】:

对命名组使用正则表达式:

import re
from collections import defaultdict

results = defaultdict(list)
matcher = re.compile(r'ip sla (?P<ipsla>\d+)|mpid (?P<mpid>\d+)'
                     r'|vlan (?P<vlan>\d+)|tag (?P<tag>\w+)')

with open("regex.txt") as f:
    for line in f:
        for match in re.finditer(matcher, line):
            results[match.lastgroup].append(match.group(match.lastgroup))

print(results)

现在您的结果可以在 (defaultdict) 字典结果中找到:

defaultdict(<class 'list'>, {
    'mpid': ['6553', '7553'],
    'vlan': ['2553', '3553'],
    'ipsla': ['2553', '3553'],
    'tag': ['CSCO5839', 'CSCO5839']
})

如有必要,您可以将各个列表放入单独的变量中,然后使用:

ipsla = results['ipsla']
vlan = results['vlan']
mpid = results['mpid']
tag = results['tag']

【讨论】:

  • 也感谢你@Antti。这正是我一直在照顾的。
【解决方案3】:

你可以这样试试:

>>> ipsla, mpid, vlan, tag = [], [], [] ,[]
>>> my_string = open('your_file', 'r')
>>> for x in re.findall("ip sla \d+|mpid \d+|vlan \d+|tag \S+", my_string):
...     if x.startswith("ip sla"):
...         ipsla.append(x.split()[2])
...     if x.startswith("mpid"):
...         mpid.append(x.split()[1])
...     if x.startswith("vlan"):
...         vlan.append(x.split()[1])
...     if x.startswith("tag"):
...         tag.append(x.split()[1])
...
>>> ipsla
['2553', '3553']
>>> mpid
['6553', '7553']
>>> vlan
['2553', '3553']
>>> tag
['CSCO5839']

【讨论】:

  • 谢谢。一个观察:这种方法会省略相同的值?例如:tag。正如您可能注意到的,它具有相同的值,并且当您对其进行测试时,它只出现过一次。如果有更多不同的值,它们都会被打印出来?
【解决方案4】:

我建议这个代码:

import re

sla = [] # Declare the list variables
mpid = []
vlan = []

with open("regex.txt","r") as myFile:              # Open the file
    p = re.compile(r'(sla|mpid|vlan)\s+(\d+)')     # Create regex
    for m in p.finditer(myFile.read()):            # Find the match in the current input
        if m.group(1) == 'sla':
            sla.append(m.group(2))                 # Add a match to the corresponding list
        if m.group(1) == 'mpid':
            mpid.append(m.group(2))
        if m.group(1) == 'vlan':
            vlan.append(m.group(2))

Python demo

import re
s = """ip sla logging traps
ip sla 2553
ethernet jitter mpid 6553 domain Gravity vlan 2553 num-frames 100 interval 100
tag CSCO5839
frequency 300
ip sla schedule 2553 life forever start-time now
ip sla 3553
ethernet jitter mpid 7553 domain Gravity vlan 3553 num-frames 100 interval 100
tag CSCO5839
frequency 300
ip sla schedule 3553 life forever start-time now"""
sla = [] # Declare the list variables
mpid = []
vlan = []

p = re.compile(r'(sla|mpid|vlan)\s+(\d+)') # Create regex
for m in p.finditer(s):                  # Find the match in the current input
    if m.group(1) == 'sla':
        sla.append(m.group(2))              # Add a match to the corresponding list
    if m.group(1) == 'mpid':
        mpid.append(m.group(2))
    if m.group(1) == 'vlan':
        vlan.append(m.group(2))

print(sla)
print(mpid)
print(vlan)

输出:

['2553', '3553'] # sla
['6553', '7553'] # mpid
['2553', '3553'] # vlan

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2020-10-12
    • 1970-01-01
    相关资源
    最近更新 更多