: '''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'''. <> Read the information regarding [string] for the real details of this subcommand. "string map ..." was introduced as one of the [Changes in Tcl/Tk 8.1.1]. It provides the ability to translate portions of a string from one value to another. For instance: ======None % string map {abc 1 ab 2 a 3 1 0} "1abcaababcabababc" 01321221 ====== As you can see, while you cannot use regular expressions to identify the strings to ''map'', if you have a series of translations to perform, using string map means that you make one pass through the string rather than multiples. [[ [Regular expressions] are the weapon of choice for some people, to the extent that they fail to notice superior RE-free solutions. "string map ..." is worth learning, in the sense that it solves several important problems that are clumsy with REs.]] 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. ---- Here's an example from [jenglish] that [lvirden] thought was pretty neat: ====== string map -nocase { "<" "<" ">" ">" "≤" "<=" "≥" ">=" } $whatever ====== ---- [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. ---- [rpremuz] (2009-01-08) An example for using the '''string map''' command can be seen in the [text_replacer.tcl] script. <> ---- **See also** * [string] * [regsub] <> Tcl syntax help | Command | String Processing