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 {
我希望 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 {