Соответствие строковому образцу с 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
Я хотел бы захватить только последний элемент в иерархии, которая не продолжается с большим количеством элементов, ограниченных символом ".". Т.е. я хотел бы добавить все экземпляры в список (конечное имя элемента может быть любым).
Если пользователь хочет выбрать 2-й уровень иерархии, сравнение должно разрешить только эти элементы сверху:
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"
}
}
}
1 ответ
Я не могу сказать, что понимаю, почему вы делаете циклы, как в вашем вопросе, поэтому я покажу немного другой фрагмент кода. Я считаю, что вы легко сможете реализовать решение самостоятельно, если я покажу вам, как работает мой. Сопоставление выполняется путем подсчета количества точек:
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
(который может напрямую возвращать количество выполненных подстановок) или разделить элемент на точки, а затем подсчитать количество полученных подэлементов, но я нашел эту вики, где она показывает, используя string map
самый быстрый метод в целом.