select/match a Section in Python

0

I'm trying to match each section of any Link State type from OSPF Database as shown in CLI_Output below using following regex in python:

regex = r'\n\n(\s+\S+( \S+)?(.+?)\n\n)(\s+\S+( \S+)?)?'
section = re.findall(regex,_original_result, re.M)

But I get only (the 1st) one line after the heading line

i.e.
                Router Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2

here my CLI-Output:

CLI_Output = '''
                Router Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2
10.200.254.252  10.200.254.252  97          0x80000003 0x00501E 3

                Net Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.254.242  10.189.254.242  1452       0x80001cf4 0xefab
10.189.0.242    10.189.0.242    1452       0x80001cf4 0xefab

                Summary Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum     Route
10.189.127.0    10.189.254.242  10         0x80001cde 0x6602     10.189.127.0/29
10.200.0.0      10.200.254.251  130        0x80000001 0x002675   10.200.0.0/16
172.18.200.1    10.200.254.251  109        0x80000001 0x00B5CB   172.18.200.1/32

                ASBR-Summary Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.127.3    10.189.254.242  10         0x80001c30 0xc14a

                Router Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.127.3    10.189.127.3    1707       0x80001d5e 0xa509   1
10.189.254.242  10.189.254.242  10         0x80001ce0 0x8ec2   1

                Net Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.127.2    10.189.254.243  70         0x80001c31 0xdb72

                Summary Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum    Route
10.189.254.240  10.189.254.242  371        0x80001cda 0x8a71     10.189.254.240/29
10.189.254.240  10.189.254.243  1813       0x80001cda 0x8476     10.189.254.240/29

                ASBR-Summary Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.7.250    10.189.254.242  1442       0x8000154f 0x165e
10.189.7.250    10.189.254.243  1242       0x8000154d 0x1461

                Router Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2
10.189.254.243  10.189.254.243  1552       0x80001ce8 0x164e   1

                Net Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum
10.200.254.241  10.200.254.251  1277 80000001 ef90  0002

                Summary Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum     Route
0.0.0.0         10.200.254.251  1317 80000001 b7b0  0002 0.0.0.0/0
0.0.0.0         10.200.254.252  1317 80000001 b1b5  0002 0.0.0.0/0

                NSSA-external Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age  Seq#     CkSum Flag Route         Tag
10.200.1.0      172.18.200.1    365  800011cb 6f90  0031 E2 10.200.1.0/24   0
10.200.2.0      172.18.200.1    1735 800011c7 6c96  0031 E2 10.200.2.0/24   0
10.200.3.0      172.18.200.1    1775 800011c9 5da2  0031 E2 10.200.3.0/24   0

                AS External Link States

Link ID         ADV Router      Age  Seq#     CkSum Flag Route         Tag
0.0.0.0         10.189.7.250    384  800129e9 9a51  0012 E2 0.0.0.0/0       0
2.3.4.0         10.189.7.250    1154 80007a7a 1fe2  0012 E2 2.3.4.0/24      0
10.112.0.0      10.189.7.250    1084 8000d7e3 b31d  0012 E2 10.112.0.0/21   0

Could someone help me, how should my regex looks for to get the complete section?

i.e.
                Router Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2
10.200.254.252  10.200.254.252  97          0x80000003 0x00501E 3

Many thanks in advance Matrix154

python
regex
match
multiline
findall
asked on Stack Overflow Jan 16, 2019 by matrix154

2 Answers

0

Like I mentioned in my comments, I believe reading line by line is easier:

record = 0
results = []

for line in CLI_Output.split("\n"):
    # skip empty lines
    if line == "" and record < 2:
        continue

    # if Router Link is in header
    if line.find('Router Link') > -1:
        record = 1
        continue

    # headers
    if record == 1:
        record = 2
        continue

    # If we are here, we are getting the data lines
    if record == 2 and line != "":
        results.append(line)
    elif line == "":
        record = 0  # use break here if you want to stop after the first chunk

print(results)

Results:

['10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2',
 '10.200.254.252  10.200.254.252  97          0x80000003 0x00501E 3',
 '10.189.127.3    10.189.127.3    1707       0x80001d5e 0xa509   1',
 '10.189.254.242  10.189.254.242  10         0x80001ce0 0x8ec2   1',
 '10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2',
 '10.189.254.243  10.189.254.243  1552       0x80001ce8 0x164e   1']

codepad demo


Though it doesn't mean it's not possible using regex, but it's more complex, like, it's honestly hard to make sense of the below if you are not used to the syntax:

^\ +(.+) Router Link States\s*(?:\([^)]+\))?\s+Link ID.+\s+((?:[^\r\n]+[\r\n]?)+)

regex101 demo

answered on Stack Overflow Jan 17, 2019 by Jerry
0

I have written many codes in perl and php and am new to python. A section selection in perl or php is easier, so I wanted to do the same in python but unfortunately unsuccessfull

@Jerry: Many thanks to you! I followed your suggestion to read the CLI Output line by line. Here is my code that i wish to share here. Maybe others need it too

import re
g = globals()

def ParseText(_original_result):
  ls_types = []
  dic = {}
  (ls_name, area_id, area_type) = ('', '', '')

  for line in _original_result.split("\n"):
    if (line.strip() and not re.search('Link ID\s+', line)):
      regex = r'^\s+(\S+|\S+ \S+) Link States'
      ls = re.findall(regex, line, re.S)
      if ls: ls_types.append(re.sub('(\s|-)', '_', ls[0]))

  ls_types = list(set(ls_types))

  for line in _original_result.split("\n"):
    if (line.strip() and not re.search('Link ID\s+', line)):
      matcher = list(re.finditer(r'^\s+(?P<ls_name>\S+( \S+)?) Link States( \(Area (?P<area_id>\S+)( \[(?P<area_type>\S+)\])?\))?', line, re.S|re.M))
      if matcher:
        ls_name = re.sub('(\s|-)', '_', matcher[0]['ls_name'])
        if not ls_name in g:
          g[ls_name] = { 'area_id': [], 'area_type': [], 'link_id': [], 'adv_rtr': [], 'age': [], 'sumary': [], 'ext_route_type': [], 'ext_route': [], 'tag': [], '$_columns' : ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag'] }
        area_id = matcher[0]['area_id']
        if matcher[0]['area_type']:
          area_type = matcher[0]['area_type']
        else:
          if area_id == '0.0.0.0': area_type = 'backbone'
          else: area_type = 'normal'
      else:
        matcher = list(re.finditer(r'^(?P<lnk_id>\S+)\s+(?P<adv_rtr>\S+)\s+(?P<age>\d+)(\s+\S+){2}(\s+(\d+\s+)?((?P<sumary>\S+)|(?P<ext_route_type>\S+)\s+(?P<ext_route>\S+)\s+(?P<tag>\d+)))?$', line, re.M|re.S))
        if matcher:
          if ls_name != 'AS_External':
            g[ls_name]['area_id'].append(area_id)
            g[ls_name]['area_type'].append(area_type)
          g[ls_name]['link_id'].append(matcher[0]['lnk_id'])
          g[ls_name]['adv_rtr'].append(matcher[0]['adv_rtr'])
          g[ls_name]['age'].append(matcher[0]['age'])
          if matcher[0]['sumary']:
            g[ls_name]['sumary'].append(matcher[0]['sumary'])
          if matcher[0]['ext_route_type']:
            g[ls_name]['ext_route_type'].append(matcher[0]['ext_route_type'])
          if matcher[0]['ext_route']:
            g[ls_name]['ext_route'].append(matcher[0]['ext_route'])
          if matcher[0]['tag']:
            g[ls_name]['tag'].append(matcher[0]['tag'])

  for LS in g:
    if LS in ls_types:
      dic[LS]= g[LS]     

  return dic

CLI_Output = '''
Forinet $get router info ospf database brief



                Router Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2
10.189.254.242  10.189.254.242  371        0x80001ce0 0x2847   1
10.189.254.243  10.189.254.243  1552       0x80001ce8 0x164e   1
10.200.254.251  10.200.254.251  93          0x80000003 0x002052 3
10.200.254.252  10.200.254.252  97          0x80000003 0x00501E 3

                Net Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.254.242  10.189.254.242  1452       0x80001cf4 0xefab

                Summary Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum     Route
10.189.127.0    10.189.254.242  10         0x80001cde 0x6602     10.189.127.0/29
10.189.127.0    10.189.254.243  1452       0x80001cdc 0x6405     10.189.127.0/29
10.200.0.0      10.200.254.251  130        0x80000001 0x002675   10.200.0.0/16
10.200.0.0      10.200.254.252  146        0x80000001 0x00207A   10.200.0.0/16
172.18.200.1    10.200.254.251  109        0x80000001 0x00B5CB   172.18.200.1/32
172.18.200.1    10.200.254.252  108        0x80000001 0x00AFD0   172.18.200.1/32

                ASBR-Summary Link States (Area 0.0.0.0)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.127.3    10.189.254.242  10         0x80001c30 0xc14a
10.189.127.3    10.189.254.243  60         0x80001c4b 0x856a

                Router Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.127.3    10.189.127.3    1707       0x80001d5e 0xa509   1
10.189.254.242  10.189.254.242  10         0x80001ce0 0x8ec2   1
10.189.254.243  10.189.254.243  70         0x80001ce6 0x80c7   1

                Net Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.127.2    10.189.254.243  70         0x80001c31 0xdb72

                Summary Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum    Route
10.189.254.240  10.189.254.242  371        0x80001cda 0x8a71     10.189.254.240/29
10.189.254.240  10.189.254.243  1813       0x80001cda 0x8476     10.189.254.240/29
10.200.254.250  10.189.254.242  1442       0x80001548 0x0673     10.189.254.250/32
10.200.254.250  10.189.254.243  1242       0x80001548 0xff78     10.189.254.250/32

                ASBR-Summary Link States (Area 1.1.1.1)

Link ID         ADV Router      Age        Seq#       Checksum
10.189.7.250    10.189.254.242  1442       0x8000154f 0x165e
10.189.7.250    10.189.254.243  1242       0x8000154d 0x1461

                Router Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum Link Count
10.189.7.250    10.189.7.250    1102       0x80012fa1 0x6b32   2
10.189.254.242  10.189.254.242  371        0x80001ce0 0x2847   1
10.189.254.243  10.189.254.243  1552       0x80001ce8 0x164e   1

                Net Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum
10.200.254.241  10.200.254.251  1277 80000001 ef90  0002

                Summary Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age        Seq#       Checksum     Route
0.0.0.0         10.200.254.251  1317 80000001 b7b0  0002 0.0.0.0/0
0.0.0.0         10.200.254.252  1317 80000001 b1b5  0002 0.0.0.0/0

                NSSA-external Link States (Area 2.2.2.2 [NSSA])

Link ID         ADV Router      Age  Seq#     CkSum Flag Route              Tag
10.200.1.0      172.18.200.1    365  800011cb 6f90  0031 E2 10.200.1.0/24   0
10.200.2.0      172.18.200.1    1735 800011c7 6c96  0031 E2 10.200.2.0/24   0
10.200.3.0      172.18.200.1    1775 800011c9 5da2  0031 E2 10.200.3.0/24   0
10.200.4.0      172.18.200.1    1555 800011c9 43be  0031 E2 10.200.4.0/22   0
10.200.8.0      172.18.200.1    1585 800011c8 28d3  0031 E2 10.200.8.0/24   0
10.200.234.0    172.18.200.1    1525 800011c7 6aaf  0031 E2 10.200.234.0/24 0

                AS External Link States

Link ID         ADV Router      Age  Seq#     CkSum Flag Route              Tag
0.0.0.0         10.189.7.250    384  800129e9 9a51  0012 E2 0.0.0.0/0       0
2.3.4.0         10.189.7.250    1154 80007a7a 1fe2  0012 E2 2.3.4.0/24      0
10.112.0.0      10.189.7.250    1084 8000d7e3 b31d  0012 E2 10.112.0.0/21   0
10.112.189.0    10.189.7.250    144  8000e95e 84fa  0012 E2 10.112.189.0/24 0
10.158.189.0    10.189.7.250    124  800129db 9df5  0012 E2 10.158.189.0/24 0
10.180.128.0    10.189.7.250    1264 800129da 15ad  0012 E2 10.180.128.0/21 0
10.188.0.0      10.189.7.250    1314 800129d5 2b4d  0012 E2 10.188.0.0/18   0
10.189.0.0      10.189.7.250    1344 800129d8 320a  0012 E2 10.189.0.0/21   0
10.189.8.0      10.189.7.250    1504 8000d057 0801  0012 E2 10.189.8.0/23   0
10.189.10.0     10.189.7.250    334  800129da e246  0012 E2 10.189.10.0/24  0
10.189.11.0     10.189.7.250    1534 800129da d750  0012 E2 10.189.11.0/24  0
10.189.14.0     10.189.7.250    1204 800129e5 a079  0012 E2 10.189.14.0/24  0
10.189.15.0     10.189.7.250    784  8000c59c 2ca1  0012 E2 10.189.15.0/29  0
10.189.20.0     10.189.7.250    914  800129e0 68b0  0012 E2 10.189.20.0/24  0

'''

print (ParseText(CLI_Output))

The Output look like this (the order while apendig is sticky, so no worry about reordering issue:

{
  'Router': {
    'area_id': ['0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0', '1.1.1.1', '1.1.1.1', '1.1.1.1', '2.2.2.2', '2.2.2.2', '2.2.2.2'],
    'area_type': ['backbone', 'backbone', 'backbone', 'backbone', 'backbone', 'normal', 'normal', 'normal', 'NSSA', 'NSSA', 'NSSA'],
    'link_id': ['10.189.7.250', '10.189.254.242', '10.189.254.243', '10.200.254.251', '10.200.254.252', '10.189.127.3', '10.189.254.242', '10.189.254.243', '10.189.7.250', '10.189.254.242', '10.189.254.243'],
    'adv_rtr': ['10.189.7.250', '10.189.254.242', '10.189.254.243', '10.200.254.251', '10.200.254.252', '10.189.127.3', '10.189.254.242', '10.189.254.243', '10.189.7.250', '10.189.254.242', '10.189.254.243'],
    'age': ['1102', '371', '1552', '93', '97', '1707', '10', '70', '1102', '371', '1552'],
    'sumary': ['2', '1', '1', '3', '3', '1', '1', '1', '2', '1', '1'],
    'ext_route_type': [],
    'ext_route': [],
    'tag': [],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  },
  'Net': {
    'area_id': ['0.0.0.0', '1.1.1.1', '2.2.2.2'],
    'area_type': ['backbone', 'normal', 'NSSA'], 'link_id':['10.189.254.242', '10.189.127.2', '10.200.254.241'],
    'adv_rtr': ['10.189.254.242', '10.189.254.243', '10.200.254.251'],
    'age': ['1452', '70', '1277'],
    'sumary': ['0002'],
    'ext_route_type': [],
    'ext_route': [],
    'tag': [],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  },
  'Summary': {
    'area_id': ['0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0', '0.0.0.0', '1.1.1.1', '1.1.1.1', '1.1.1.1', '1.1.1.1', '2.2.2.2', '2.2.2.2'],
    'area_type': ['backbone', 'backbone', 'backbone', 'backbone','backbone', 'backbone', 'normal', 'normal', 'normal', 'normal', 'NSSA', 'NSSA'],
    'link_id': ['10.189.127.0', '10.189.127.0', '10.200.0.0', '10.200.0.0', '172.18.200.1', '172.18.200.1', '10.189.254.240', '10.189.254.240', '10.200.254.250', '10.200.254.250', '0.0.0.0', '0.0.0.0'],
    'adv_rtr': ['10.189.254.242', '10.189.254.243', '10.200.254.251', '10.200.254.252', '10.200.254.251', '10.200.254.252', '10.189.254.242', '10.189.254.243', '10.189.254.242', '10.189.254.243', '10.200.254.251', '10.200.254.252'],
    'age': ['10', '1452', '130', '146', '109', '108', '371', '1813', '1442', '1242', '1317', '1317'],
    'sumary': ['10.189.127.0/29', '10.189.127.0/29', '10.200.0.0/16', '10.200.0.0/16', '172.18.200.1/32', '172.18.200.1/32', '10.189.254.240/29', '10.189.254.240/29', '10.189.254.250/32', '10.189.254.250/32', '0.0.0.0/0', '0.0.0.0/0'],
    'ext_route_type': [],
    'ext_route': [],
    'tag': [],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  },
  'ASBR_Summary': {
    'area_id': ['0.0.0.0', '0.0.0.0', '1.1.1.1', '1.1.1.1'],
    'area_type': ['backbone', 'backbone', 'normal', 'normal'],
    'link_id': ['10.189.127.3', '10.189.127.3', '10.189.7.250', '10.189.7.250'],
    'adv_rtr': ['10.189.254.242', '10.189.254.243', '10.189.254.242', '10.189.254.243'],
    'age': ['10', '60', '1442', '1242'],
    'sumary': [],
    'ext_route_type': [],
    'ext_route': [],
    'tag': [],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  },
  'NSSA_external': {
    'area_id': ['2.2.2.2', '2.2.2.2', '2.2.2.2', '2.2.2.2', '2.2.2.2', '2.2.2.2'],
    'area_type': ['NSSA', 'NSSA', 'NSSA', 'NSSA', 'NSSA', 'NSSA'],
    'link_id': ['10.200.1.0', '10.200.2.0', '10.200.3.0', '10.200.4.0', '10.200.8.0', '10.200.234.0'],
    'adv_rtr': ['172.18.200.1', '172.18.200.1', '172.18.200.1', '172.18.200.1', '172.18.200.1', '172.18.200.1'],
    'age': ['365', '1735', '1775', '1555', '1585', '1525'], 'sumary':[],
    'ext_route_type': ['E2', 'E2', 'E2', 'E2', 'E2', 'E2'],
    'ext_route': ['10.200.1.0/24', '10.200.2.0/24', '10.200.3.0/24', '10.200.4.0/22', '10.200.8.0/24', '10.200.234.0/24'], 'tag':['0', '0', '0', '0', '0', '0'],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  },
  'AS_External': {
    'area_id': [],
    'area_type': [],
    'link_id': ['0.0.0.0', '2.3.4.0', '10.112.0.0', '10.112.189.0', '10.158.189.0', '10.180.128.0', '10.188.0.0', '10.189.0.0', '10.189.8.0', '10.189.10.0', '10.189.11.0', '10.189.14.0', '10.189.15.0', '10.189.20.0'],
    'adv_rtr': ['10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250', '10.189.7.250'],
    'age': ['384', '1154', '1084', '144', '124', '1264', '1314', '1344', '1504', '334', '1534', '1204', '784', '914'],
    'sumary': [],
    'ext_route_type': ['E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2', 'E2'],
    'ext_route': ['0.0.0.0/0', '2.3.4.0/24', '10.112.0.0/21', '10.112.189.0/24', '10.158.189.0/24', '10.180.128.0/21', '10.188.0.0/18', '10.189.0.0/21', '10.189.8.0/23', '10.189.10.0/24', '10.189.11.0/24', '10.189.14.0/24', '10.189.15.0/29', '10.189.20.0/24'],
    'tag': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'],
    '$_columns': ['area_id', 'area_type', 'link_id', 'adv_rtr', 'age', 'sumary', 'ext_route_type', 'ext_route', 'tag']
  }
}
answered on Stack Overflow Jan 18, 2019 by matrix154 • edited Jan 18, 2019 by matrix154

User contributions licensed under CC BY-SA 3.0