I have a problem with writing correct regex. Maybe someone can help me?

我写一个正确的正则表达式有问题。也许有人可以帮助我?

I have output from two network devices:

我有两个网络设备的输出:

1

VRF NAME1 (VRF Id = 2); default RD 9200:1; default VPNID <not set>
Old CLI format, supports IPv4 only
Flags: 0xC
Interfaces:
Gi1/1/1                 Gi1/1/4

2

VRF NAME2 (VRF Id = 2); default RD 101:2; default VPNID <not set>
Interfaces:
Gi0/0/3                  Gi0/0/4                  Gi0/1/4

I need extract interface name from both.

我需要从两者中提取接口名称。

I have regex:

我有正则表达式:

 rx = re.compile("""
              VRF\s(.+?)\s\(.*RD\s(.*);.*[\n\r]
              ^.*$[\n\r]
              ^.*$[\n\r]
              ^.*$[\n\r]
              (^.*)
              """,re.MULTILINE|re.VERBOSE)

But it is only works for first text, it skips 4 lines and 5 line is exactly what I need. However there are many routers that returning output like 2. The question is how ignore unknown amount of line and for example find line with Interfaces word and extract next line after "Interfaces:"

但它只适用于第一个文本,它跳过4行,5行正是我需要的。然而,有许多路由器返回输出2,问题是如何忽略未知数量的行,例如找到带有接口字的行并在“接口:”之后提取下一行。

3 个解决方案

#1


1

EDIT: after providing us with more input, the answer is corrected.

编辑:在为我们提供更多输入后,答案得到纠正。

There are many ways to solve this. Look at regex101. The regex

有很多方法可以解决这个问题。看看regex101。正则表达式

(?s)VRF\s([^\s]+)\s.*?(?:RD\s([\d.]+:\d|<not\sset>));.*?Interfaces:(?:\r*\n)\s*(.*?)(?:\r*\n)

read in a complete record and captures the Name, RD value and line following Interfaces.

读取完整记录并捕获名称,RD值和接口后面的行。

Explanation:

(?s)                           # single line mode: make "." read anything,
                               # including line breaks
VRF                            # every records start with VRF
\s                             # read " "
([^\s]+)                       # group 1: capture NAME VRF
\s                             # read " "
.*?                            # lazy read anything
(?:                            # start non-capture group
 RD\s                          # read "RD "
(                              # group 2
  [\d.]+:\d                    # number or ip, followed by ":" and a digit
  |                            # OR
  <not\sset>                   # value "<not set>"
)                              # group 2 end
)                              # non-caputure group end
;                              # read ";"
.*?                            # lazy read anything
Interfaces:                    # read "Interfaces:"
(?:\r*\n)                      # read newline
\s*                            # read spaces
(.*?)                          # group 3: read line after "Interfaces:"
(?:\r*\n)                      # read newline

Let's look at a test script. I've cut down on the length of the records in the script a bit, but the message still stands.

我们来看一下测试脚本。我已经减少了脚本中记录的长度,但消息仍然存在。

$ cat test.py
import os
import re

pattern = r"(?s)VRF\s([^\s]+)\s.*?(?:RD\s([\d.]+:\d|<not\sset>));.*?Interfaces:(?:\r*\n)\s*(.*?)(?:\r*\n)"

text = '''\
VRF BLA1 (VRF Id = 2); default RD 9200:1; default VPNID <not set>
Old CLI format, supports IPv4 only
Flags: 0xC
Interfaces:
  Gi1/1/1.451              Gi1/1/4.2019
Address family ipv4 unicast (Table ID = 0x2):
  VRF label allocation mode: per-prefix
Address family ipv6 unicast not active
Address family ipv4 multicast not active

VRF BLA2 (VRF Id = 1); default RD <not set>; default VPNID <not set>
New CLI format, supports multiple address-families
Flags: 0x1808
Interfaces:
  Gi0
Address family ipv4 unicast (Table ID = 0x1):
  Flags: 0x0
Address family ipv6 unicast (Table ID = 0x1E000001):
  Flags: 0x0
Address family ipv4 multicast not active\
'''

for rec in text.split( os.linesep + os.linesep):
    m = re.match(pattern, rec)
    if m:
        print("%s\tRD: %s\tInterfaces: %s" % (m.group(1), m.group(2), m.group(3)))

which results in:

这导致:

$ python test.py
BLA1    RD: 9200:1  Interfaces: Gi1/1/1.451              Gi1/1/4.2019
BLA2    RD: <not set>   Interfaces: Gi0

更多相关文章

  1. 【Python】Python脚本实现抢券
  2. 运维利器:钉钉机器人脚本告警(Linux Python 篇)
  3. 从bash脚本传递参数到python解释器
  4. Python脚本如何获取当前环节和用户等信息
  5. python mysql 导出到mongodb脚本
  6. 脚本结束后如何运行进程并退出?
  7. 如何获得正在运行的Python脚本的路径?(复制)
  8. Shell脚本更改带变量的目录
  9. Linux(Debian)设置开机自启动脚本

随机推荐

  1. android 布局中 layout_gravity、gravity
  2. android数字证书-签名(步骤)
  3. Android(安卓)图形架构
  4. android中内存调试信息的解读
  5. Android原生(Native)C开发之二:framebuffe
  6. Android Web development Note
  7. Android持久化技术之SharedPreferences存
  8. Android的多媒体框架Opencore代码阅读
  9. Android(安卓)的 ListView 的CheckBox标
  10. 不能找到相应的target