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

时间:2019-06-08 07:18:44

标签: regex tcl tk

我在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]

1 个答案:

答案 0 :(得分:0)

要将一个文本子字符串替换为另一个子字符串,我们可以使用几种不同的技术。这取决于您的实际操作。例如,如果要将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]
}

这里的关键技巧是您以相反的顺序进行替换(这就是为什么您需要注意在lrange之前使用lreverse的原因),以便仍然替换的索引不会因替换而改变。


从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]] "}"
}}}]