究竟你做了什么?
当我在tclsh 中输入上面的命令时,它会显示错误 -
% set test1 [list prefix_abc_3 abc_1 abc_2 AAA_0]
prefix_abc_3 abc_1 abc_2 AAA_0
% set test2 abc
abc
% regsub -all ${test2}_[1-9] [list] test1
invalid command name "1-9"
我不确定您要做什么。您首先将test1 初始化为列表。然后通过将其传递给 regsub 将其视为 字符串。这是完全合法的做法,但可能表明您对某事感到困惑。您是否尝试通过对prefix_abc_3、abc_1、abc_2 和AAA_0 中的每一个应用四次来测试您的替换?你当然可以按照自己的方式去做,但更自然的方式是这样做
foreach test $test1 {
regsub $pattern $test [list] testResult
puts stdout $testResult
}
再一次,你想用你的替代来实现什么?看起来好像您正在尝试将 stringabc 替换为空字符串,即完全删除它。将[list] 作为空字符串传递是完全有效的,但再次可能表明列表和字符串之间存在混淆。
要达到你想要的结果,你需要做的就是在你的模式中添加一个前导空格,传递一个空格作为替换字符串并转义方括号,即
regsub -all " ${test2}_\[-9\]" $test1 " " test1
但我怀疑这是一个虚构的例子,你真的在尝试做一些稍微不同的事情。
编辑
我建议要获得一个仅包含那些与您的模式不完全匹配的列表条目的列表
proc removeExactMatches {input} {
set result [list]; # Initialise the result list
foreach inputElement $input {
if {![regexp {^abc_[0-9]$} $inputElement]} {
lappend result $inputElement
}
}
return $result
}
set test1 [removeExactMatches [list prefix_abc_3 abc_1 abc_2 AAA_0]]
注意事项:
i) 我根本不使用 regsub。
ii) 尽管在列表和字符串之间切换是安全和合法的,但这一切都需要时间,而且它会掩盖我想要做的事情,所以我尽可能避免它。您似乎有一个字符串列表,并且想要删除其中的一些,所以这就是我在建议的解决方案中使用的。 Tcl 中的正则表达式命令处理 strings,所以我将它们传递给字符串。
iii) 为确保列表元素完全匹配,我使用 ^ 和 $ 将模式锚定到要匹配的字符串的开头和结尾。
iv) 为防止解释器识别正则表达式模式中的 [1-9] 并尝试执行(不存在的)命令 1-9,我将整个模式字符串括在大括号内。
v) 为了更通用,我可能想将模式以及输入列表(字符串)传递给 proc,在这种情况下,我会这样做
proc removeExactMatches {inputPattern input} {
.
.
.
set pattern "^"
append pattern $inputPattern
append pattern "\$"
.
.
.
if {![regub $pattern $inputElement]} {
.
.
.
}
set test1 [removeExactMatches {abc_[1-9]} {prefix_abc_3 abc_1 abc_2 AAA_0}]
尽量减少必须转义的字符数。 (实际上我可能不会在 proc 中使用引号作为开始和结束锚点 - 它们并不是真正需要的,而且我是一个懒惰的打字员!)
查看您的原始问题,您似乎只想更改模式的 abc 部分,在这种情况下,您可能只想将其传递给您的 proc 并附加 _[0-9]作为其中的锚点 - 如果您沿着这条路线走,请不要忘记转义方括号或使用大括号。