TCL正则表达式

时间:2016-07-07 21:45:24

标签: regex tcl

我有两种类型的接口“Ethernet9 / 12/1和Ethernet8 / 34”。我想使用单个正则表达式解析这两种类型的接口。

我试图通过以下方式实现这一目标:

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

此代码适用于Ethernet9 / 12/1。但是,相同的正则表达式不适用于Ethernet8 / 34。我需要帮助才能在使用TCL的单一正则表达式中实现这一目标。

请帮助。

3 个答案:

答案 0 :(得分:0)

您需要使用非捕获组使最后一部分成为可选项:

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

请参阅IDEONE Tcl demo

输出:

Ethernet
8/34
8
34

非捕获组仅用于对子模式进行分组,并且不会干扰您已定义的稍后要使用的捕获组。

答案 1 :(得分:0)

只需使用?选择第二部分:

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

regex101

上进行测试

注意:我使用/转义了您的\字符,但这可能具有特定的风格。

答案 2 :(得分:0)

如果没有将所有处理集中在正则表达式中,则代码变得更易于管理。

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 {}

文档: lassignlistputsregexpsetsplitSyntax of Tcl regular expressions