有关Regex算法的问题(不一定与EXPECT相关) [英] Questions on Regex algorithm (not necessarily EXPECT related)
问题描述
我正在尝试创建一个正则表达式以捕获设备的邻居详细信息(以下示例输出).
I'm trying to create a regex to capture the neighbor detail of my devices (example output below).
我可以对每行进行硬编码,但是我正在寻找更好的解决方案.也许学习一种新算法.
I could hard code each individual line, but I'm looking for a better solution. maybe learn a new algorithm.
我对捕获设备ID(HOST1),接口(GigabitEthernet0/1)和端口ID(GigabitEthernet2/43)感兴趣.每个邻居并将其存储在以逗号分隔的列表中.
I'm interested in capturing Device ID (HOST1), Interface (GigabitEthernet0/1), and Port ID (GigabitEthernet2/43). for each neighbor and store it in a list comma separated.
send "show cdp neighbors detail\r"
expect {
-re "-+\r\nDevice ID: (\[^\r]+)\r\n\[^\r]+\r\n\[^\r]+\r\n\[^\r]+\r\nInterface: (\[^,]+),\[^:]+: (\[^\r]+)\r\n" {
set neig $expect_out(1,string)
set localint $expect_out(2,string)
set rmint $expect_out(3,string)
lappend neighbor "$neig,$localint,$rmint"
exp_continue
}
"#" {}
}
NUMBER1#sho cdp neighbor detail
-------------------------
Device ID: HOST1
Entry address(es):
IP address: 10.10.10.1
Platform: cisco WS-C6506-E, Capabilities: Router Switch IGMP
Interface: GigabitEthernet0/1, Port ID (outgoing port): GigabitEthernet2/43
Holdtime : 126 sec
Version :
Cisco IOS Software, s72033_rp Software (s72033_rp-ADVIPSERVICESK9_WAN-M), Version 12.2(33)SXJ8, RELEASE SOFTWARE (fc5)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2014 by Cisco Systems, Inc.
Compiled Thu 21-Aug-14 09:14 by prod_rel_team
advertisement version: 2
VTP Management Domain: 'ZONE'
Native VLAN: 3
Duplex: full
Management address(es):
IP address: 10.10.10.1
-------------------------
Device ID: HOST2
Entry address(es):
IP address: 10.10.10.2
Platform: cisco WS-C6506-E, Capabilities: Router Switch IGMP
Interface: GigabitEthernet0/2, Port ID (outgoing port): GigabitEthernet2/43
Holdtime : 139 sec
Version :
Cisco IOS Software, s72033_rp Software (s72033_rp-ADVIPSERVICESK9_WAN-M), Version 12.2(33)SXJ8, RELEASE SOFTWARE (fc5)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2014 by Cisco Systems, Inc.
Compiled Thu 21-Aug-14 09:14 by prod_rel_team
advertisement version: 2
VTP Management Domain: 'ZONE'
Native VLAN: 3
Duplex: full
Management address(es):
IP address: 10.10.10.2
NUMBER1#
我上面的代码正在工作,只是在寻找更智能的方法?更轻松?或其他捕获数据的方式.而不是那个可怕的正则表达式.
My above code is working, just looking for a more intelligent? easier? or different way of capturing the data. Instead of that god awful regex.
foreach dev $neighbor {
puts "$dev"
}
Output:
HOST1,GigabitEthernet0/1,GigabitEthernet2/43
HOST2,GigabitEthernet0/2,GigabitEthernet2/43
在旁注中,如何在期望范围内使用"{}"匹配出现次数"? 例如:
on a side note, how can I match "occurrences" using "{}"within expect? for example:
-re "(\r\n\[^\r]+){3}"
将匹配3行
推荐答案
我认为最好使用更简单的匹配项,但要使用更多的匹配子句.这往往会使代码更容易理解.
I think it is going to be best to use simpler matches but more match clauses. That tends to give easier to understand code.
send "show cdp neighbors detail\r"
expect {
-re {^Device ID: (\w+)} {
set neig $expect_out(1,string)
exp_continue
}
-re {^Interface: ([\w/]+), [^:]+: ([\w/]+)} {
set localint $expect_out(1,string)
set rmint $expect_out(2,string)
lappend neighbor "$neig,$localint,$rmint"
exp_continue
}
"#" {}
}
感兴趣的关键事项:
- 我将RE放在花括号中,因此在正则表达式中几乎不需要太多的反斜杠.这大大提高了可读性!
- 我正在使用
[\w/]
来匹配单词字符"(基本上是字母数字)加/
.如果没有前面的观点,那将是丑陋的. -
^
锚定到行的开头. ($
到最后,但是我们在这里不需要它.) - 我假设每个设备(您关心的)都将有一个
Device ID
行,然后再有一个Interface
行,这使我可以独立匹配行并将其值存储在一个简单的变量中当另一个子句命中时被拾取.这是简化整体RE的关键:我们不需要匹配所有内容,只需匹配我们真正感兴趣的部分即可.
- I'm putting the REs in braces so I don't need nearly so many backslashes in the regular expressions. This helps readability a lot!
- I'm using
[\w/]
to match "word characters" (basically the alphanumerics) plus/
. That would be ugly without the preceding point though. ^
anchors to the start of the line. ($
to the end, but we don't need it here.)- I'm assuming that every device (that you care about) will have a
Device ID
line followed later by anInterface
line, allowing me to match the lines independently and just store the value in a simple variable for it to be picked up when the other clause hits. This is the key to making the overall REs simpler: we don't need to match everything, just the bits that we're really interested in.
{3}
(或更常见的是{3,42}
)确实匹配匹配项.它通常不是正确的工具,您需要对自己真正要处理的内容非常小心,但是它确实有效.
{3}
(or more generally {3,42}
) does match occurrences. It's often not the right tool and you need to be very careful about what you are really dealing with, but it does work.
这篇关于有关Regex算法的问题(不一定与EXPECT相关)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!