简体   繁体   English

匹配多行python正则表达式

[英]Matching Multiple lines python regex

I have a file which contains configurations. 我有一个包含配置的文件。 I need to find a pattern to match multiple lines in the configuration file. 我需要找到一种模式来匹配配置文件中的多行。

Basically, I am looking for the following types of line: 基本上,我正在寻找以下类型的线:

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

In file the block is as: 在文件中,该块为:

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

Later on, I need to get the name of virtual server: virtualserver1 description (virtualserver1.aaa.com) if present and the multiple virtual-addresses and port (172.16.211.153 and https) if present. 稍后,我需要获取虚拟服务器的名称:virtualserver1 description(virtualserver1.aaa.com)(如果存在)以及多个虚拟地址和端口(172.16.211.153和https)(如果存在)。

I tried various combinations trying to match the blocks but was not successful. 我尝试了各种组合来尝试匹配块,但未成功。

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

This gives me only first line and second line as output for all the configurations present. 对于所有存在的配置,这仅给我第一行和第二行作为输出。

What pattern should I use to match all blocks? 我应该使用什么模式来匹配所有块?

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

Regex documentation : 正则表达式文档

(?=...) matches if ... matches next, but doesn't consume any of the string. (?=...)如果...匹配,则匹配,但不使用任何字符串。 This is called a lookahead assertion. 这称为先行断言。

(?<=...) matches if the current position in the string is preceded by a match for ... that ends at the current position. (?<=...)如果在字符串中的当前位置之前有匹配项...的匹配项,则该匹配项在当前位置结束。 This is called a positive lookbehind assertion. 这称为肯定隐式断言。

$ is used so that last match is captured as well. $来捕获最后一个匹配项。

Well, in case your blocks can have no more than 2 'match'es , you can try using this regex: 好吧, 如果您的代码块不能超过2个“ match” ,可以尝试使用此正则表达式:

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?))?

These named groups will hold corresponding data: 这些命名组将保存相应的数据:

servername
description
IP
HTTP1
HTTP2

See 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM