我在编写正确的正则表达式时遇到问题。也许有人可以帮助我?
我有两个网络设备的输出:
1
Sub Demo()
'Dim i As Long
Dim cell As Range, cell_adr As Range 'declare cell as Range
'Dim arr() As String
Dim mth_exp_PM As String 'this value is taken from a different workbook and it matches one row header value
'i = 0
For Each cell In Range(Range("D1"), Range("D1").End(xlToRight).Offset(0, -1)).Cells
'ReDim Preserve arr(i)
'arr(i) = cell
'If arr(i) = mth_exp_PM Then
If cell = mth_exp_PM Then
Set cell_adr = cell
Debug.Print cell_adr.Address
End If
'i = i + 1
Next cell
End Sub
2
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
我需要从两者中提取接口名称。
我有正则表达式:
VRF NAME2 (VRF Id = 2); default RD 101:2; default VPNID <not set>
Interfaces:
Gi0/0/3 Gi0/0/4 Gi0/1/4
但它只适用于第一个文本,它跳过4行,5行正是我需要的。但是,有许多路由器返回输出,如2。 问题是如何忽略未知数量的行,例如找到带有接口字的行并在&#34;接口之后提取下一行:&#34;
答案 0 :(得分:1)
积极的背后隐藏
(小于?= ...) 确保给定的模式匹配,从表达式中的当前位置结束。图案必须具有固定的宽度。不消耗任何字符。
正则表达式(?<=Interfaces:\n).+
匹配每行后的整行&#34;接口:&#34;
我在regex101.com上测试了它,它完全适用于你的两个例子。
答案 1 :(得分:1)
编辑:在向我们提供更多输入后,答案已得到纠正。
有很多方法可以解决这个问题。看看regex101。正则表达式
(?s)VRF\s([^\s]+)\s.*?(?:RD\s([\d.]+:\d|<not\sset>));.*?Interfaces:(?:\r*\n)\s*(.*?)(?:\r*\n)
读取完整记录并捕获Interfaces
后面的名称,RD值和行。
说明:
(?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
让我们看一下测试脚本。我已经减少了脚本中记录的长度,但是消息仍然存在。
$ 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)))
导致:
$ python test.py
BLA1 RD: 9200:1 Interfaces: Gi1/1/1.451 Gi1/1/4.2019
BLA2 RD: <not set> Interfaces: Gi0
答案 2 :(得分:0)
有多个选项,但最接近初始尝试的选项使用可选的非捕获线:
rx = re.compile("""
VRF\s(.+?)\s\(.*RD\s(.*);.*[\n\r]
(?:^.*$[\n\r])?
(?:^.*$[\n\r])?
Interfaces:[\n\r]
(.*)""",re.MULTILINE|re.VERBOSE)
然而,第一行对我来说也很奇怪,并且没有编译(缺少右括号),但(?:^.*$[\n\r])?
在您的应用程序中有效。