是否可以使用regsub在表达式中进行不同的替换?
示例:
set a ".a/b.c..d/e/f//g"
现在,在这个表达式中,是否可以替换
“.
”为“yes
”
“..
”为“no
”
“/
”为“true
”
单个regsub命令中的“//
”为“false
”?
答案 0 :(得分:8)
regsub
,没有。对于这种事情有一个长期的功能请求(需要用匹配信息评估命令的结果替换)但是到目前为止它还没有被采取行动。
但在这种情况下,你可以使用string map
做你想做的事情:
set a ".a/b.c..d/e/f//g"
set b [string map {".." "no" "." "yes" "//" "false" "/" "true"} $a]
puts "changed $a to $b"
# changed .a/b.c..d/e/f//g to yesatruebyescnodtrueetrueffalseg
请注意,在构建地图时,如果任何from-value是另一个的前缀,则应首先放置较长的from-value。 (这是因为string map
实现会按照您在...中列出的顺序检查要进行的更改。)
可以使用regsub
和subst
在两个步骤中进行多目标替换,但除了非常复杂的情况之外,我不建议使用它!一个不错的string map
更容易使用。
答案 1 :(得分:2)
您也可以尝试自己动手。这是一个草案proc
,您可以将其作为起点。它不是生产准备好的,你必须小心,因为第一个之后的替换处理已经被替换的字符串。
这些是参数:
options
是一个选项列表,将传递给每次调用regsub
resubList
是键/值对的列表,其中键是正则表达式,值是替换string
是您要替换的字符串这是程序,它只是多次调用regsub
,对resubList
中的每个元素调用一次,最后返回最后一个字符串。
proc multiregsub {options resubList string} {
foreach {re sub} $resubList {
set string [regsub {*}$options -- $re $string $sub]
}
return $string
}