请给我一些意见。我有以下输入的TCL正则表达式。
set a { Descriptor Blocks:
10.132.224.74 (Tunnel42), from 10.132.224.74, Send flag is 0x0
Composite metric is (2032896/128256), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55000 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 1
Originating router is 10.128.9.65
10.135.0.86 (GigabitEthernet0/1), from 10.135.0.86, Send flag is 0x0
Composite metric is (2033152/2032896), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55010 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 2
Originating router is 10.128.9.65
Internal tag is 200 }
从上面我想要像两个列表元素一样分开,正则表达式应该跟随单词分开。
这里有两个接口输出,一个用于
10.132.224.74 (Tunnel42)
界面,另一个是
10.135.0.86 (GigabitEthernet0/1)
如果没有以&#34开头的行;内部标记为"在"发起路由器之后 是"它应该划分为"起源路由器是"作为一个线 列表元素。
如果有一行"内部标签是"之后可以使用 "始发路由器是"它应该划分为"内部标记是" 作为一个列表
我期待输出像
{Tunnel42), from 10.132.224.74, Send flag is 0x0
Composite metric is (2032896/128256), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55000 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 1
Originating router is 10.128.9.65
10.135.0.86 (GigabitEthernet0/1), from 10.135.0.86, Send flag is 0x0
Composite metric is (2033152/2032896), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55010 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 2
Originating router is 10.128.9.65
Internal tag is 200
答案 0 :(得分:1)
您可以使用textutil
模块轻松完成此操作:
package require textutil
textutil::split::splitx $a {\n(?=\s*\d)}
这会将原始文本拆分为三个项目的列表:“描述符块:”子字符串和两个块的每个项目。它的工作原理是找到一个换行符,其中换行符和可选的空格后跟一个数字。删除换行符,但保留前导空格和数字。
Core-Tcl解决方案:
替换
regsub -all -line {^(?=\s*\d)} $a \n
将文本分成三部分(第一部分是“描述符块:”子字符串),方法是在每个块之前插入一个额外的换行符。这个解决方案显然只取决于每个块中的第一行,以一个数字开头,前面有空格。 -line
选项会在换行后使^
锚定。
请注意,这会产生一个包含三个部分的文本,而不是三个元素的列表:如果需要,您需要在每个双行中断处打破文本。处理此问题的另一种方法是让regsub
替换插入一个不会出现在文本中的字符,然后拆分该字符,例如
split [regsub -all -line {^(?=\s*\d)} $a @] @
答案 1 :(得分:1)
更通用的方法可以将输入分成行并根据需要解析它们
set a { Descriptor Blocks:
10.132.224.74 (Tunnel42), from 10.132.224.74, Send flag is 0x0
Composite metric is (2032896/128256), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55000 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 1
Originating router is 10.128.9.65
10.135.0.86 (GigabitEthernet0/1), from 10.135.0.86, Send flag is 0x0
Composite metric is (2033152/2032896), route is Internal
Vector metric:
Minimum bandwidth is 4096 Kbit
Total delay is 55010 microseconds
Reliability is 255/255
Load is 1/255
Minimum MTU is 1380
Hop count is 2
Originating router is 10.128.9.65
Internal tag is 200 }
set tunnelStart 0
set interfaceStart 0
set tunnelInfo {}
set interfaceInfo {}
set result {}
foreach line [split $a \n] {
if {[regexp {\(Tunnel\d+\)} $line]} {
# If suppose, we already identified 'tunnelInfo' and extracted it, then that variable won't be empty
if {$tunnelInfo ne {}} {
regsub {\n$} $tunnelInfo {} tunnelInfo
# So, appending it to 'result'
lappend result $tunnelInfo
# Then, resetting the 'tunnelInfo'
set tunnelInfo {}
}
set tunnelStart 1
set interfaceStart 0
} elseif {[regexp {\(GigabitEthernet\d+/\d+\)} $line]} {
# Same reason as explained above
if {$interfaceInfo ne {}} {
regsub {\n$} $interfaceInfo {} interfaceInfo
lappend result $interfaceInfo
set interfaceInfo {}
}
set interfaceStart 1
set tunnelStart 0
}
if {$tunnelStart} {
#Appending each line along with '\n'
append tunnelInfo $line\n
} elseif {$interfaceStart} {
append interfaceInfo $line\n
}
}
#Removing the last '\n' alone
regsub {\n$} $tunnelInfo {} tunnelInfo
regsub {\n$} $interfaceInfo {} interfaceInfo
# At last checking if the variable is not empty, append it to 'result'
if {$tunnelInfo ne {}} {
lappend result $tunnelInfo
}
if {$interfaceInfo ne {}} {
lappend result $interfaceInfo
}
puts $result
你可以将它们放入程序&在任何想要分开输入的地方打电话。如果假设您的输入有多个隧道和接口行信息,您可以重新编写代码以相应地解析它。