Tcl 字符串映射:如何映射到左大括号

Tcl string map: how to map to open brace

我希望 catch " 转换为 newcatch {。我尝试了以下方法:

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

我想要 newcatch { 在输出中。请建议我该怎么做。如果您找到替代方法,请考虑如何以最少的修改采用上述方法。此外,为什么不需要转义 " (如果我转义它与提供的字符串不匹配。

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

除了转义匹配字符串中的文字大括号外,我还转义了 space 字符。即 newcatch\ \{

代码可以写成

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

更新: 这不是关于哪个是必要的。这是由于您想要的输出。

string map的语法如下,

string map ?-nocase? mapping string

现在忘记 -nocase 标志。为了简单起见,可以写成,

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

键值对集合可以用双引号或者用space分隔的大括号书写。不同之处在于,使用大括号时,根本不会发生替换,而是用字面值来处理。

即它可以是 "foo bar hello world"{foo bar hello world}

您的主要要求是映射文字大括号。考虑以下示例,

puts "{"
puts {\{}

虽然前者会准确地生成文字大括号,但后者会打印大括号和反斜杠。即 \{ 这是因为,当在大括号内转义时,它将按字面意思进行处理。

同样的逻辑也适用于 string map 命令。由于您需要匹配 {.

更新二:

先试试这个。

puts {{}}

输出结果为 {}puts {{}之所以失败,是因为不平衡。 Tcl 会认为您在 {} 内打开了一个左大括号 { 并期望再有一个右大括号,因为它用在大括号之间。如前所述,puts "{" 之所以有效,是因为它不是用大括号解释的,而是用双引号解释的。

回到我们的故事。为了使 Tcl 将左大括号解释为文字大括号,我们使用反斜杠转义为 \{

现在,又一条规则生效了。使用大括号,替换根本不会发生,它将被视为我之前引用过的文字值,使得\{ 字面上打印为 \{。 :)

更新 3:

我们有点跑题了。不是吗?不管怎样,让我试试。

首先,为了转义左大括号,我们在其前面加上反斜杠。这可以防止 tcl 抛出 missing close brace error 消息。

正如我们所知,大括号中的任何内容都是 treated/printed。

我们有什么?只有 \{。这就是它按原样打印的原因。

坦白说,如果Mr.Donal同学看到这个post,他可以快点讲课作为答案。:)

在双引号中阅读映射器可能更容易。

catch.tcl

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

输出:

./catch.tcl
newcatch {