TCL:如何使用大括号"{...}"引用一个字符串中的单个大括号"{"?

dhr*_*eel 2 string tcl quoting curly-braces

我试图使用大括号来定义字符串{ },而不是双引号的" ",所以我没有逃避几个字符(如$,[,]).

但是,当我的字符串需要在其中包含单个字符串时,我遇到了一些问题{.
我知道我可以通过简单地使用双引号字符串来实现这一点{,但是如何使用"花括号字符串"来实现它?

例如.我想要puts以下字符串' proc foo {} { '到stdout.

puts "proc foo \{ \} \{"给了我想要的输出:' proc foo {} { '

然而,puts { proc foo \{ \} \{ }给我:' proc foo\{\}\{ '通过字面打印反斜杠.

如果我跳过反斜杠,puts { proc foo { } {它会抱怨缺少支撑.

此外,如果所需的字符串中有匹配的闭括号,它可以正常工作.
puts { proc foo { } { } }给了我预期的:' proc foo {} {} '

在"花括号"字符串中逃避单个不匹配的花括号的正确方法是什么?

Pet*_*rin 5

对不起,支撑字符串的服务条款要求您为每个打开的大括号配备一个匹配的闭括号.使用不匹配大括号的唯一方法是使用反斜杠引用/转义它们,但不会执行反斜杠替换,因此反斜杠会与单独的大括号一起进入字符串.

这并不意味着你不能构造你想要的字符串,例如:

set foo { proc foo { } }
# ->  proc foo { } 
append foo "{ "
# ->  proc foo { } { 
Run Code Online (Sandbox Code Playgroud)

(顺便说一下,你不需要用双引号字符串反斜杠," proc foo { } { "也可以.)

但是,您构建的字符串似乎暗示您正在脚本中构建过程定义,并以错误的方式进行操作.而不是像这样组装定义:

set foo { proc foo { } }
# ->  proc foo { } 
append foo "{ "
# ->  proc foo { } { 
append foo { puts foo }
# ->  proc foo { } {  puts foo 
append foo " }"
# ->  proc foo { } {  puts foo  }
Run Code Online (Sandbox Code Playgroud)

你应该做这个:

set name foo
set args {}
set body {puts foo}
proc $name $args $body
Run Code Online (Sandbox Code Playgroud)

它直接定义了程序.如果你需要它作为一个字符串,包装如下:

set foo [list proc $name $args $body]
# -> proc foo {} {puts foo}
Run Code Online (Sandbox Code Playgroud)

是的,我list用来构造一个字符串.这是因为proc $name $args $body用双引号括起来会导致命令列表结构的丢失.我创建一个列表,然后使用该列表的字符串表示作为字符串.

如果你这样做,你正在使用 Tcl解释规则并利用它们,而不是反对它们.这意味着更少的工作和更少的错误.

文档:append,list,proc,set