** Synopsis ** : '''string map''' ''?'''''-nocase'''''? charMap string'' Replaces characters in ''string'' based on the key-value pairs in ''charMap''. ''charMap'' is a list of ''key value key value ...'' as in the form returned by '''[array get]'''. Each instance of a key in the string will be replaced with its corresponding value. If -'''nocase''' is specified, then matching is done without regard to case differences. Both ''key'' and ''value'' may be multiple characters. Replacement is done in an ordered manner, so the key appearing first in the list will be checked first, and so on. ''string'' is only iterated over once, so earlier key replacements will have no effect for later key matches. For example, ====== string map {abc 1 ab 2 a 3 1 0} "1abcaababcabababc" ====== will return the string '''01321221'''. [[string map]] is often an alternative to [Regular expressions], and is sometimes more convenient. ** See Also ** * [string] * [regsub] ** History ** "string map ..." was introduced as one of the [Changes in Tcl/Tk 8.1.1]. Byte-compiles since 8.4 ** Examples ** ======none % string map {%} "I" ====== [[string map]] loses the power of [regular expressions] when searching for substrings, but sometimes regular expresssions are overkill. ---- Here's an example from [jenglish] that [lvirden] thought was pretty neat: ====== string map -nocase { "<" "<" ">" ">" "≤" "<=" "≥" ">=" } $whatever ====== [rpremuz] 2009-01-08: An example for using the '''string map''' command can be seen in the [text_replacer.tcl] script. ** Caveats ** When using [[string map]] to generate Tcl code, it's a good idea to use fully-delimited placeholders, to avoid matching, eg., %TOKEN in addition to %TO. ====== ====== ** Regex Map ** [IL] 8/19/2006 How about a regex_map? In a language where we already have switch by regex, I think we can take this to the next level :). It's so trivial to do, but when included in the api itself, makes developers go ga-ga. then they get to say stuff like "out of the box" a lot. ====== proc regex_map { str args } { if { [llength $args] % 2 == 1} { set msg "wrong \# args: should be " append msg "regex value ?regex value?...\"" return -code error $msg } foreach {regex value} $args { regsub -all $regex $str $value str } return $str } ====== % regex_map "phil is a cool guy" {co+[^ ]} sweet {[pP]hil} Ivan Ivan is a sweet guy [DKF]: Interesting, but difficult to make work correctly when there are overlapping patterns. Not impossible though; I guess you could make a prototype that builds a single RE that searches for each of the replacements at the same time, and then combine that with the -start and -indices options to [regexp] to make the matching useful, and then do that in a loop and etc. Tricky to get right (there are a lot of awkward corners, like subexpressions), but once there is a Tcl version (maybe in tcllib?) we can think about the design of the C version and (after that, possibly, if enough people want it) the design of something for the core. ** Discussion ** See [Counting characters in a string] on how [string map] is the best performer (again to [RS]'s surprise...) - because it gets byte-compiled since 8.4. <> Tcl syntax help | Command | String Processing