你究竟执行了什么?
当我将上面的命令键入时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
}
再说一次,你想用你的替代来实现什么?看起来好像您正试图abc
用空字符串替换该字符串,即完全删除它。[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 中的正则表达式命令处理字符串,所以我将它们传递给字符串。
iii) 为确保列表元素完全匹配,我将模式锚定到我使用^
and匹配的字符串的开头和结尾$
。
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]
的锚点 - 不要忘记逃避如果您沿着这条路线走,请使用方括号或使用大括号。