需要帮助regsub的tcl命令使用

时间:2013-07-26 10:57:05

标签: regex tcl

我是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。这里有没有人知道如何只在列表中重新配置确切的单词?

我试图通过网络找到解决方案,但无法获得任何线索/提示。感谢这里有人可以帮助我。

2 个答案:

答案 0 :(得分:1)

regexp中的

\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_3abc_1abc_2AAA_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}}以及其中的锚点 - 如果你走这条路线,不要忘记逃避方括号或使用大括号。