与 tcl 匹配的字符串模式
String pattern matching with tcl
我是 tcl 的新手,我正在尝试仅捕获以下用户指定的层次结构深度:
top.run.end
top.run.something.end
top.simple.end1
top.simple.end2
top.simple.something.end1
top.simple.something.end2
top.simple.something.else.end
top.simple.something.else.other.name.end
我只想捕获层次结构中的最后一个元素,该层次结构不会继续包含更多由“.”分隔的元素。 IE。我想将所有实例附加到列表中(最终元素名称可以是任何东西)。
如果用户想要 select 第二层次,比较应该只允许来自上面的这些元素:
top.run.end
top.simple.end1
top.simple.end2
如果用户指定第 3 层级,那么我想抓取这些元素:
top.simple.something.end1
top.simple.something.end2
第 4 层级:
top.simple.something.else.end
等等……我已经编写了除字符串比较之外的所有代码,但我尝试过的一切似乎都没有达到我想要的效果。
set num_hierarchy 3; # how many levels deap to search for "end"
set num_facs [ gtkwave::getNumFacs ]; # returns number of elements in file
for {set group_to_add 1} {$group_to_add <= $num_hierarchy} {incr group_to_add} {
set wave [list]
for {set i 0} {$i < $num_facs } {incr i} {
set fac_name [ gtkwave::getFacName $i ]; #returns string in form noted above
set indx [string <how to compare strings??> $fac_name]
if {$indx == <match>} {
lappend wave "$fac_name"
}
}
}
我不能说我理解你为什么要像你的问题中那样做循环,所以我会展示一个稍微不同的代码片段。如果我可以向您展示我的工作原理,我相信您应该能够轻松地自己实施该解决方案。通过计算点数来匹配:
set elements {
top.run.end
top.run.something.end
top.simple.end1
top.simple.end2
top.simple.something.end1
top.simple.something.end2
top.simple.something.else.end
top.simple.something.else.other.name.end
}
set depth_required 3
set wave [list]
foreach element $elements {
# initial length of element
set i_len [string length $element]
# final length of element after removing dots
set f_len [string length [string map {. ""} $element]]
# thus number of dots
set n_dots [expr {$i_len-$f_len}]
# if the number equals the required hierarchy, then we got one
if {$n_dots == $depth_required} {
lappend wave $element
}
}
wave
然后包含:
top.run.something.end top.simple.something.end1 top.simple.something.end2
您可以使用 regsub
(它可以直接 return 执行的替换次数)或将元素拆分为点,然后计算结果子元素的数量,但我发现this wiki 其中显示使用 string map
是总体上最快的方法。
我是 tcl 的新手,我正在尝试仅捕获以下用户指定的层次结构深度:
top.run.end
top.run.something.end
top.simple.end1
top.simple.end2
top.simple.something.end1
top.simple.something.end2
top.simple.something.else.end
top.simple.something.else.other.name.end
我只想捕获层次结构中的最后一个元素,该层次结构不会继续包含更多由“.”分隔的元素。 IE。我想将所有实例附加到列表中(最终元素名称可以是任何东西)。
如果用户想要 select 第二层次,比较应该只允许来自上面的这些元素:
top.run.end
top.simple.end1
top.simple.end2
如果用户指定第 3 层级,那么我想抓取这些元素:
top.simple.something.end1
top.simple.something.end2
第 4 层级:
top.simple.something.else.end
等等……我已经编写了除字符串比较之外的所有代码,但我尝试过的一切似乎都没有达到我想要的效果。
set num_hierarchy 3; # how many levels deap to search for "end"
set num_facs [ gtkwave::getNumFacs ]; # returns number of elements in file
for {set group_to_add 1} {$group_to_add <= $num_hierarchy} {incr group_to_add} {
set wave [list]
for {set i 0} {$i < $num_facs } {incr i} {
set fac_name [ gtkwave::getFacName $i ]; #returns string in form noted above
set indx [string <how to compare strings??> $fac_name]
if {$indx == <match>} {
lappend wave "$fac_name"
}
}
}
我不能说我理解你为什么要像你的问题中那样做循环,所以我会展示一个稍微不同的代码片段。如果我可以向您展示我的工作原理,我相信您应该能够轻松地自己实施该解决方案。通过计算点数来匹配:
set elements {
top.run.end
top.run.something.end
top.simple.end1
top.simple.end2
top.simple.something.end1
top.simple.something.end2
top.simple.something.else.end
top.simple.something.else.other.name.end
}
set depth_required 3
set wave [list]
foreach element $elements {
# initial length of element
set i_len [string length $element]
# final length of element after removing dots
set f_len [string length [string map {. ""} $element]]
# thus number of dots
set n_dots [expr {$i_len-$f_len}]
# if the number equals the required hierarchy, then we got one
if {$n_dots == $depth_required} {
lappend wave $element
}
}
wave
然后包含:
top.run.something.end top.simple.something.end1 top.simple.something.end2
您可以使用 regsub
(它可以直接 return 执行的替换次数)或将元素拆分为点,然后计算结果子元素的数量,但我发现this wiki 其中显示使用 string map
是总体上最快的方法。