如何替换 TCL 中花括号内的数据?

How to replace datas inside a curly braces in TCL?

我在TCL中有两个列表,我想在同一行用这两个列表替换两个不同的花括号数据(请检查示例)。这种情况可以使用什么类型的正则表达式或替换方法在 TCL 中?在这种情况下可以使用 sed 命令吗?

EXAMPLE 1 :-
 I have to go to park [ -from {orange grey} houses -to {white pink} houses ] 

LIST 1 : set from_bus {red green blue}
LIST 2 : set to_bus {yellow black}

EXPECTED OUTPUT 1 :-
I have to go to park [ -from {red green blue} houses -to {yellow black} houses]
EXAMPLE 2 :-
 I want fruits [ -from {apple mango} fruits -to {orange banana} fruits ] 

LIST 1 : set from_fruits {grapes watermelon}
LIST 2 : set to_fruits {lime plums}

EXPECTED OUTPUT 2 :-
I want fruits [ -from {grapes watermelon} fruits -to {lime plums} fruits]

要用另一个文本子串替换一个文本子串,我们可以使用几种不同的技术。这取决于你实际在做什么。例如,如果您想将 orange grey 所有 个实例替换为 red green blue 并将 white pink 的所有实例替换为 yellow black,我们使用字符串映射命令:

set mapping [list "orange grey" "red green blue" "white pink" "yellow black"]
set output [string map $mapping $inputText]

按位置这样做有点复杂。因此,如果我们要用索引替换所有 { 大括号 } 的内容,我们会这样做:

set replacements [list "red green blue" "yellow black"]
set ranges [regexp -all -inline -indices {\{[^{}]+\}} $inputText]
set lastIndex [expr {min([llength $replacements], [llength $ranges]) - 1}]
set output $inputText
foreach range [lreverse [lrange $ranges 0 $lastIndex]] \
        replacement [lreverse [lrange $replacements 0 $lastIndex]] {
    set repl "{$replacement}"
    set output [string replace $output {*}$range $repl]
}

这里的关键技巧是你以相反的顺序进行替换(这就是为什么你需要在 lreverse 之前小心使用 lrange)这样索引仍然是被替换的不会被替换改变。


从 8.7 开始,您将可以改为执行此操作:

set replacements [list "red green blue" "yellow black"]
set idx -1
set output [regsub -command -all {\{[^{}]+\}} $inputText {apply {- {
    global idx replacements
    string cat "{" [lindex $replacements [incr idx]] "}"
}}}]