我正在编写一个实用程序(恰好在Python中),该实用程序正在以TCL脚本的形式生成输出。给定一些任意字符串变量(不是Unicode),我想产生像

set s something

...将设置TCL变量's对于那个精确的字符串,无论其中有什么奇怪的字符。在没有太奇怪的情况下,我不想使输出比所需的更混乱。我相信一种体面的方法是

  1. 如果字符串不为空,仅包含字母数字,而某些字符喜欢 .-_ (但绝对不是 $"{}\)然后可以按原样使用;

  2. 如果仅包含可打印的字符,没有双引号或卷发括号(并且不会以后斜切结束),则简单地放置 {} 周围;

  3. 否则,放 "" 使用后周围 \ 逃脱 " { } \ $ [ ] , 和 \nnn 逃脱非打印字符。

问题:是否需要逃脱双引号的整个字符?我在文档中找不到这一点。我是否错过了一些东西(我几乎错过了(2)的字符串,例如 )。

我知道还有许多其他字符串可以引用 {}, ,但似乎很难轻松地识别它们。另外,如果您不介意在TCL输出中实际上存在,则(尤其是Newline)看起来(特别是Newline)看起来可以。

有帮助吗?

解决方案

您实际上只需要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}
}

编辑鉴于您的评论,您可以执行以下操作:

  • 逃脱 [] {}$
  • 包裹整个输出 set s [subst { $output } ]

TCL的美丽在于它具有非常简单的语法。除了上面的3个,没有其他字符需要逃脱。

编辑2 最后一次尝试。

如果您通过 subst 一些选择,您只需要逃脱 \{}

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

但是,您需要提出正则表达式,以将不可打印的字符转换为其ESC代码。

祝你好运!

其他提示

一旦您进入双重引用的字符串,TCL就有很少的Metacharacters,可以通过将后斜切放在前面来引用。您必须引用的字符是 \ 本身, $[, ,但也被引用被认为是好的做法 ], {} 因此脚本本身可以嵌入。 (TCL自己的 list 命令执行此操作,除了它实际上没有包装双引号,因此它还处理后斜切,并且还将尝试在“ nice”字符串上使用其他技术。这样做有一种算法,但我建议不要为代码中的如此多的复杂性而烦恼。简单的通用规则对于正确的编码要好得多。)

第二步是将数据输入TCL。如果要生成文件,最好的选择是将其写成UTF-8并使用 -encoding tclsh/wish的选项或 source 命令明确说明编码是什么。 (如果您在相同的过程中,请将UTF-8数据写入字符串并评估该数据。工作完成。)该选项(在TCL 8.5中引入)专门用于处理此类问题:

source -encoding "utf-8" theScriptYouWrote.tcl

如果不可能,您将不得不回到添加其他报价。最好的事情是假设您只有可用的ASCII支持(最低的公共分母)并引用其他所有内容 作为第一段中描述的引号的单独步骤. 。引用引用,将每个Unicode字符从u+00080转换为表单的逃脱顺序 \uXXXX 其中xxxx正好是四个十六进制数字[1] 另外两个是字面角色。不要使用 \xXX 形式,因为它具有一些“令人惊讶的”错误(a)。


[1] TCL中有一个关于处理基本多语言窗格之外的字符的公开错误, 部分 其中是 \u 表格无法应付。幸运的是,在实践中,非BMP字符仍然很少见。

要正确地做到这一点,您还应该指定编码python字符串所在,通常是sys.getDefaultEncoding()。否则,您可能会在将其转换为TCL时藏品编码。

如果您的字符串中有二进制数据,并且希望TCL二进制字符串因此始终有效:

data = "".join("\\u00%02x" % ord(c) for c in mystring)
tcltxt = "set x %s" % data

虽然看起来像十六进制垃圾场,但是,这是一个十六进制...

如果使用任何特殊编码,例如UTF-8,则可以通过使用Convert From/converttor和适当的Python Idiom来增强该编码。

data = "".join("\\u00%02x" % ord(c) for c in myutf8string)
tcltext = "set x [encoding convertfrom utf-8 %s]" % data

当然,您可以稍微完善一点,避免使用所有非特殊字符的 u编码,但是无论如何,上面都是安全的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top