TCL的常规字符串引用

gre*_*ggo 17 tcl quoting

我正在编写一个实用程序(恰好在python中),它以TCL脚本的形式生成输出.给定python中的一些任意字符串变量(不是unicode),我想生成一个类似的TCL行

set s something
Run Code Online (Sandbox Code Playgroud)

...将TCL变量' s'设置为该精确字符串,无论其中包含什么奇怪的字符.没有变得太奇怪,我不想让输出比需要的更麻烦.我相信一个体面的方法

  1. 如果字符串不是空的并且只包含字母数字,而某些字符.-_(但绝对不是$"{}\)那么它可以原样使用;

  2. 如果它只包含可打印字符而没有双引号或花括号(并且不以反斜杠结尾),那么只需将{}它放在一边;

  3. 否则,""在使用\转义后放置它" { } \ $ [ ] ,并\nnn转义为非打印字符.

问题:是否需要在双引号内转义的完整字符集?我在文档中找不到这个.我是否错过了一些东西(我几乎错过了(2)的字符串不能以\结尾).

我知道还有许多其他字符串可以引用 {},但似乎很难轻易识别它们.此外,看起来非打印字符(特别是换行符)可以使用(2)如果您不介意它们确实存在于TCL输出中.

Byr*_*ock 17

你真的只需要2个规则,

  • 逃避花括号
  • 用大括号包裹输出

您不必担心换行符,不可打印的字符等.它们在文字字符串中有效,并且TCL具有出色的Unicode支持.

set s { 
this is
a 
long 
string. I have $10 [10,000 cents] only curly braces \{ need \} to be escaped.
\t is not  a real tab, but '    ' is. "quoting somthing" :
{matchin` curly braces are okay, list = string in tcl}
}
Run Code Online (Sandbox Code Playgroud)

编辑 根据您的评论,您可以执行以下操作:

  • 逃避[] {}$
  • 将整个输出包装进去 set s [subst { $output } ]

Tcl的美妙之处在于它具有非常简单的语法.除了上述3之外,没有其他角色需要被转义.

编辑2最后一次尝试.

如果你传递了subst一些选项,你只需要逃避\{}

set s [subst -nocommands -novariables { $output } ]

你需要提出一个正则表达式来将不可打印的字符转换为它们的转义代码.

祝好运!

  • 但我发现这一点:在找到匹配的末端卷曲时,转义卷曲会阻止它们被考虑,但反斜杠不会被删除(因为它们是双引号)即结果仍然会有我添加到原始卷曲中的反斜杠. (2认同)
  • 拜托拜伦!很有帮助. (2认同)

Don*_*ows 6

一旦你进入双引号字符串,Tcl的元字符很少,并且可以通过在它们前面放一个反斜杠来引用它们.你必须报字符\本身,$[,但它被认为是很好的做法,也引用],{}让脚本本身是嵌入.(Tcl自己的list命令执行此操作,除了它实际上没有包装双引号所以它也处理反斜杠,它也会尝试在"漂亮"字符串上使用其他技术.有一个算法可以做到这一点,但我建议不要打扰代码中的复杂程度很高;简单的通用规则对于正确的编码要好得多.)

第二步是将数据导入Tcl.如果要生成文件,最好的选择是将其写为UTF-8并使用-encodingtclsh/wish选项或source命令来明确说明编码是什么.(如果您在同一个进程中,请将UTF-8数据写入字符串并对其进行评估.作业完成.)该选项(在Tcl 8.5中引入)专门用于处理此类问题:

source -encoding "utf-8" theScriptYouWrote.tcl
Run Code Online (Sandbox Code Playgroud)

如果那是不可能的,那么你将不得不退回添加额外的报价.最好的事情是假设您只提供ASCII支持(一个很好的最低公分母)并引用其他所有内容作为第一段中描述的引用的单独步骤.要引用,将每个Unicode字符从U + 00080转换为格式的转义序列,\uXXXX其中XXXX正好是四个十六进制数字[1],另外两个是文字字符.不要使用\xXX表格,因为它有一些"令人惊讶"的错误(唉).


[1] Tcl中存在一个关于处理Basic Multilingual Pane之外的字符的漏洞,其中一部分\u表单无法应对.幸运的是,非BMP角色在实践中仍然相当罕见.