如何在Tcl中的文本中搜索次文本?

时间:2019-03-06 05:56:25

标签: list tcl

我是tcl的新手,我有一个列表1-adam 2-john 3-mark,并且必须接受用户输入,我必须在列表中更改要更改的序列,并在用户想要更改列表时使其成为列表1-adam 2-john 3-jane系列3?

我正在尝试:

set names [split "1-adam 2-john 3-mark" " "]
puts "Enter the serial no:" 
set serial [gets stdin]
set needle $serial\-
foreach name $names {
    #here I'm trying to find  and overwrite'
}

1 个答案:

答案 0 :(得分:2)

您有一个好的开始。要替换列表中的元素,通常可以使用lreplace,对于这种特殊情况,也可以使用lset。这两个函数都需要替换元素的索引,因此,我建议使用for循环而不是foreach

set names [split "1-adam 2-john 3-mark" " "]
puts "Enter the serial no:"
set serial [gets stdin]
puts "Enter new name:"     ;# Might want to add something like this for the new name
set new_name [gets stdin]
set needle $serial-        ;# You do not really need to escape the dash
for {set i 0} {$i < [llength $names]} {incr i} {
    set name [lindex $names $i]
    if {[string match $needle* $name]} {
        set names [lreplace $names $i $i $needle$new_name]
    }
}
puts $names
# 1-adam 2-john 3-jane

使用lset将是:

lset names $i $needle$new_name

另一种方法是使用lsearch查找需要更改的元素的索引,在这种情况下,您将不需要循环:

set names [split "1-adam 2-john 3-mark" " "]
puts "Enter the serial no:"
set serial [gets stdin]
puts "Enter new name:"
set new_name [gets stdin]
set needle $serial-

set index [lsearch $names $needle*]
if {$index > -1} {
    lset names $index $needle$new_name
} else {
    puts "No such serial in the list!"
}

puts $names
# 1-adam 2-john 3-jane