DurgaDatta
DurgaDatta

Reputation: 4170

Tcl string map: how to map to open brace

I expect catch " to be transformed to newcatch {. I tried the following:

% string map { {catch "} {newcatch \{} } {catch "}
newcatch \{

I wanted newcatch { in th output. Please suggest me how to do that. If you find alternative ways to do it, please also consider how the above approach can be taken with minimal modification. Additionally, why is it not ncessary to escape the " (if I escape it does not match in the supplied string.

Upvotes: 1

Views: 1483

Answers (2)

Dinesh
Dinesh

Reputation: 16428

puts [ string map { {catch "} newcatch\ \{ } {catch "}] 

Along with escaping the literal brace inside the match string, I have escaped the space character too . i.e. newcatch\ \{

The code can be written as

puts [ string map { catch\ \" newcatch\ \{ } {catch "}] 

Update : It is not about which is necessary. It is due to your desired output.

Syntax of string map is as follows,

string map ?-nocase? mapping string

Forget about the -nocase flag as of now. To make it simple, it can be written as,

string map <key1 value1 key2 value2 ... > <target-string>

The key-value pair set can be written with the help of double quotes or with braces separated by space. The difference is that with braces, substitution won't happen at all and it will be treated with literal values.

i.e. it can be "foo bar hello world" or {foo bar hello world}

Your major requirement is mapping literal brace. Consider the below examples,

puts "{"
puts {\{}

While the former will produce the literal brace exactly, later one will print brace along with a backslash. i.e. \{ This is because, when escaped inside braces, it will be taken literally.

Same logic applied with string map command also. Since you need to match with {.

Update 2:

Try this first.

puts {{}}

which will give output as {}. The reason why puts {{} failed is because it is unbalanced. Tcl will think like you have opened one left brace { inside {} and expect one more closing brace since it is used between braces. As pointed out earlier, puts "{" works because, it is not interpreted with braces, but double quotes.

Come back to our story. In order to make the Tcl to interpret the left brace as literal brace, we are escaping with backslash as \{.

Now, one more rules kicks in. With braces, substitution won't happen at all and it will be treated as literal values which I have quoted earlier, making the \{ to get printed as \{, literally. :)

Update 3:

We are going off the topic a bit. Isn't it? Anyway, let me try.

First, to escape left brace, we are prepending it with backslash. This prevents tcl from throwing missing close brace error message.

As we know, whatever resides in braces, well be treated/printed as such.

What do we have? Only \{. That's why it is printed as it is.

Frankly,If Mr.Donal Fellows see this post, he can give a quick lecture as answer.:)

Upvotes: 2

wolfhammer
wolfhammer

Reputation: 2661

It's might be easier to read the mapper in double quotes.

catch.tcl

#!/usr/bin/tclsh
set mapper { "catch \"" "newcatch \{" }
set mapped [string map $mapper {catch "}]
puts $mapped

Output:

./catch.tcl
newcatch {

Upvotes: 0

Related Questions