匹配多行python正则表达式

时间:2015-02-26 20:40:31

标签: python regex

我有一个包含配置的文件。我需要找到一个匹配配置文件中多行的模式。

基本上,我正在寻找以下类型的行:

class-map match-any virtualserver1
     description virtualserver1.aaa.com
     2 match virtual-address 172.16.211.153 tcp eq https
     3 match virtual-address 172.16.211.153 tcp eq https
class-map match-any virtual-server2
     2 match virtual-address 172.16.211.154 tcp eq http
class-map match-any vip-helloworld
     description vs-yyy.com
class-map match-any vip-myvirtualServer

在文件中,块为:

class-map match-any virtualserver1
  description virtualserver1.aaa.com
  2 match virtual-address 172.16.211.153 tcp eq https
  3 match virtual-address 172.16.211.153 tcp eq https

稍后,我需要获取虚拟服务器的名称:virtualserver1 描述(virtualserver1.aaa.com)如果存在 以及多个虚拟地址和端口(172.16.211.153和https)(如果存在)。

我尝试了各种组合试图匹配块但没有成功。

import re
fh = open('config_file.txt')
fileData = fh.read()
vipData = re.findall('^class-map match-.*\n.+', fileData,re.MULTILINE)
finalList = sorted(set(vipData))
i = 1
for data in finalList:
    print str(i) +" "+ str(data)
    i = i + 1

这只给出了第一行和第二行作为所有配置的输出。

我应该使用什么模式来匹配所有块?

2 个答案:

答案 0 :(得分:0)

re.findall(r'(?<=class-map match-any).*?(?=class-map match-any|$)', my_str, re.DOTALL)

正则表达式documentation

(?=...)匹配,如果...匹配下一个,但不消耗任何字符串。这被称为先行断言。

(?<=...)匹配,如果字符串中的当前位置前面是以当前位置结尾的...匹配。这被称为积极的外观断言。

使用

$以便捕获最后一个匹配。

答案 1 :(得分:0)

嗯,如果您的积分不能超过2&#39;匹配,您可以尝试使用此正则表达式:

class\-map\s+match\-any\s+(?P<servername>[\w-]+)(?:\s*description\s*(?P<description>[\w\.-]+))?(?:\s*\d+\s+match\s*virtual-address\s*(?P<IP>\d+\.\d+\.\d+\.\d+)\s+[^\r\n]*(?P<HTTP1>https?))?(?:\s*\d+\s+match\s*virtual-address\s*(?P<IP2>\d+\.\d+\.\d+\.\d+)\s+[^\r\n]*(?P<HTTP2>https?))?

这些命名组将包含相应的数据:

servername
description
IP
HTTP1
HTTP2

请参阅demo here

import re
p = re.compile(ur'class\-map\s+match\-any\s+(?P<servername>[\w-]+)(?:\s*description\s*(?P<description>[\w\.-]+))?(?:\s*\d+\s+match\s*virtual-address\s*(?P<IP>\d+\.\d+\.\d+\.\d+)\s+[^\r\n]*(?P<HTTP1>https?))?(?:\s*\d+\s+match\s*virtual-address\s*(?P<IP2>\d+\.\d+\.\d+\.\d+)\s+[^\r\n]*(?P<HTTP2>https?))?', re.MULTILINE | re.DOTALL)
str = u"YOUR_STRING"

re.findall(p, str)