简体   繁体   中英

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.

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:

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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