如何使用Tcl放置包含大括号{和}的字符串?

时间:2015-08-23 16:46:25

标签: escaping tcl

我正在编写代码来生成Tcl脚本,它会生成包含" puts {blah}"的脚本。

但是如果我尝试放置{},脚本将会失败。我以为逃避是' \'但它没有用:

% puts {}}
extra characters after close-brace
% puts {\}}
\}
% puts {\{}
\{

puts{{}也不起作用,但puts{{}}有效。

同样,如果\是字符串的最后一个字符,则命令将无法完成。

我已经查看了Tcl(http://www.tcl.tk/man/tcl8.5/TclCmd/Tcl.htm)的12条规则,但我没有看到解决问题的方法。

4 个答案:

答案 0 :(得分:2)

大括号可以引用大多数内容,但不能引用不平衡大括号。当你不得不停止使用大括号进行引用并使用反斜杠(可以引用任何内容,但这些引起讨厌和丑陋)时。实际上,这就是Tcl自己的列表引用引擎所做的事情。

# Double quotes can quote things in some cases.
set a "This is{ an example"
set b "and so }is this"
puts [list $a $b]
This\ is\{\ an\ example and\ so\ \}is\ this

如果您正在生成命令,则建议使用list来执行此操作,或者使用C级别的等效代码在Tcl_NewListObj()和朋友之后。这样做是对的,所以你不必这样做。 (当执行作为奖励时,它也有一些性能优化。)

答案 1 :(得分:0)

根据规则,大括号应该是平衡的,任何放在大括号之间的东西都会被字面上对待。这些是导致这种行为的原因。

% puts "{"
{
% puts "}"
}
% puts "{{}"
{{}
% 

使用双引号括起字符串。

答案 2 :(得分:0)

如果您要读取可能包含不平衡大括号的输入流并使用该流上的文本进行脚本输出,您将不得不a)计算大括号并以某种方式平衡它们,或者b)使用双引号。如果输入流包含双引号字符,则string map它们很容易转义双引号。

您可能还会从list命令中获得一些里程数,这对于转义非常聪明。如果输入为foo }bar [baz],存储在变量foo中,则可以使用命令puts [list puts $foo]输出脚本

puts foo\ \}bar\ \[baz\]

再现输入。

如果没有人需要阅读生成的脚本,另一个解决方案是将每个字符转换为字符代码,以便foo} bar成为例如{0}}。 \x66\x6f\x6f\x7d\x20\x62\x61\x72(可以直接输出)。当然可以从这种转换中排除字母数字以保持一定的可读性。这个练习的要点是你根本不需要任何引用。

可能还有更优雅的方法,但如果不了解您的数据,很难提出好的建议。

答案 3 :(得分:0)

% puts \{\}\}
{}}
% puts \{\{\}
{{}
% puts this\ is\ it\ {\}\}
this is it {}}

这可能会对你有所帮助 我刚刚使用了@Peter Lewerin的概念