TCL Regular Expression

一世执手 提交于 2020-01-06 03:03:13

问题


I have two types of interfaces "Ethernet9/12/1 and Ethernet8/34". I wanted to parse both type of interfaces using single regular expression.

I was trying to achieve this in the below manner:

set int "Ethernet9/12/1"
regexp -nocase "(.*t)((\\d+)\/(\\d+)/\(\\d+))" $int - int_type int_num mod_num port broken_port
puts $int_type
puts $int_num
puts $mod_num
puts $port
puts $broken_port

This code works for Ethernet9/12/1. But, the same regexp does not work for Ethernet8/34. I need help to achieve this in the single regexp using TCL.

Kindly help.


回答1:


You need to make the last part optional with a non-capturing group:

regexp -nocase "(.*t)((\\d+)\/(\\d+)(?:/(\\d+))?)" $int - int_type int_num mod_num port broken_port
                                    ^^^       ^^

See IDEONE Tcl demo

Output:

Ethernet
8/34
8
34

A non-capturing group is only meant to group subpatterns and does not interfere with the capturing groups you already defined to be used later.




回答2:


Just make the second part optional with ?:

(.*t)((\d+)\/(\d+)(?:\/(\d+))?) 

Tested on regex101

NOTE: I escaped your / characters with a \ but that might flavor specific.




回答3:


The code becomes a lot more manageable if one doesn't concentrate all processing within the regular expressions.

set int Ethernet9/12/1

regexp -nocase {(.+t)(.*)} $int -> int_type int_num
lassign [split $int_num /] mod_num port broken_port

puts [list $int_type $int_num $mod_num $port $broken_port]
# -> Ethernet 9/12/1 9 12 1

set int Ethernet8/34

regexp -nocase {(.+t)(.*)} $int -> int_type int_num
lassign [split $int_num /] mod_num port broken_port

puts [list $int_type $int_num $mod_num $port $broken_port]
# -> Ethernet 8/34 8 34 {}

Documentation: lassign, list, puts, regexp, set, split, Syntax of Tcl regular expressions



来源:https://stackoverflow.com/questions/38255800/tcl-regular-expression

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!