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

Regex 如何在TCL中替换大括号内的数据?,regex,tcl,tk,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 bla

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

要将文本的一个子字符串替换为另一个子字符串,我们可以使用几种不同的技术。这取决于你实际上在做什么。例如,如果要将
橙灰色
的所有实例替换为
红-绿-蓝
,将
白-粉红
的所有实例替换为
黄-黑
,我们将使用字符串映射命令:

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

我不确定我是否明白你想做什么?现在看来,你可以使用它,但如果你没有提到一些信息,你可能需要一些不同的东西。我们是按位置替换还是按要替换的文本替换?@Jerry,@Donal Fellows我有两个列表。在一个文件中,每行有两个大括号和一些数据[与示例中提到的格式相同]我想用这两个列表替换两个大括号数据。第一个列表用于第一个大括号数据,第二个列表用于第二个大括号数据。希望您现在理解我的要求。@stark也许您可以提供更多彼此尽可能不同的示例?有些事情可能会像‘我想要这个,但如果这发生了,这就是我想要的’“。基本上,我认为很难说什么总是一样的,在你试图解释的问题中什么总是在变化。@Jerry现在检查示例,输入格式总是一样的。非常感谢你给出这么好的解决方案..第一个解决方案对我有效,但我没有;我没有正确理解代码。我还没有测试第二个解决方案。是否有任何sed命令可以获得相同的解决方案?能否请您从regexp行解释您的代码?带有
-all-inline-index
选项的
regexp
命令返回一个坐标列表(嗯,索引到字符串中)在正则表达式匹配的字符串中(即索引对的列表)。然后,我们将它们与替换列表进行匹配,并将它们以相反的顺序应用于
输出
变量中输入字符串的副本(这样我们就不会弄乱索引);每次替换都使用
字符串替换
完成。
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]] "}"
}}}]