我是tcl
的新学员。使用regsub
时,我有以下问题。请考虑以下情形:
set test1 [list prefix_abc_3 abc_1 abc_2 AAA_0]
set test2 abc
regsub -all ${test2}_[1-9] $test1 [list] test1
我期待$test1 output is [prefix_abc_3 AAA_0]
但是regsub
也删除了部分匹配的字符串prefix_abc_3
。这里有没有人知道如何只在列表中重新配置确切的单词?
我试图通过网络找到解决方案,但无法获得任何线索/提示。感谢这里有人可以帮助我。
答案 0 :(得分:1)
\m and \M分别匹配单词的开头和结尾。但是你在test1
中没有一串单词,而是一个元素列表,有时会有区别,所以不要混淆两者。 regsub
仅处理字符串,lsearch与列表一起使用:
set test1 [list prefix_abc_3 abc_1 abc_2 AAA_0]
set test2 abc
set test1 [lsearch -all -inline -not -regexp $test1 "^${test2}_\[1-9\]\$"]
如果模式很简单,您可以使用-glob
选项(默认值)而不是-regexp
,也许可以节省一些处理器时间。
答案 1 :(得分:0)
你执行了哪些完全?
当我在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)为了确保列表元素完全匹配,我将模式锚定到我使用^
和$
匹配的字符串的开头和结尾。
iv)为了防止解释器识别正则表达式模式中的[1-9]并尝试执行(不存在的)命令1-9
,我将整个模式字符串括在大括号内。< / p>
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
并附加{ {1}}以及其中的锚点 - 如果你走这条路线,不要忘记逃避方括号或使用大括号。