2012-11-06 52 views
1

使用regsub可以在表达式中做不同的替换吗?有没有办法使用REGSUB做多个替代?

例如:

set a ".a/b.c..d/e/f//g" 

现在,在该表达式中,是有可能替代 “.” 为 “yes” “..” 为 “no” “/” 为 “true” “ //“作为”false“在单个regsub命令?

回答

8

With a regsub,no。对于这类事情有一个长期的功能要求(它需要用对比赛信息评估一个命令的结果进行替换),但是它迄今还没有被采取行动。

但是你可以用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 

注意构建地图时,如果有从价值是另一个的前缀,较长的距离值应该是先放。 (这是因为string map实现检查其更改为了让你列出他们...)


它可以使用regsubsubst做多目标替代的两步过程,但我除非是非常复杂的情况,否则不要建议它!一个不错的string map更容易处理。

+0

缺少的功能相当于Perl的/// e'。这种情况下的总体矫枉过正... –

2

你也可以尝试自己做。这是一份草稿proc,您可以将其作为起点。它不是生产准备好的,你必须小心谨慎,因为第一个替换后的替换工作已经替换了字符串。

这些参数:

  • options是将被传递到每个调用regsub
  • resubList的选项列表是键/值对的列表,其中关键是一个正则表达式和值是替代
  • string是要替换

字符串这是proced ure,它只是简单地调用regsub多次,对于resubList中的每个元素一次,最后返回最后一个字符串。

proc multiregsub {options resubList string} { 
    foreach {re sub} $resubList { 
     set string [regsub {*}$options -- $re $string $sub] 
    } 
    return $string 
} 
+0

请注意,由于被替换的字符串会迭代多次,所以这会对{a A a b}等情况产生意想不到的结果。这与字符串映射(http://wiki.tcl.tk/2819)不同。 –

+0

是的,我知道;也许我应该更加明确这些警告。 –

相关问题