TCL的通用字符串引用
我正在编写一个实用程序(恰好是python),它以TCL脚本的形式生成输出。给定python中的一些任意字符串变量(不是unicode),我想生成一个类似于TCL的通用字符串引用,tcl,quoting,Tcl,Quoting,我正在编写一个实用程序(恰好是python),它以TCL脚本的形式生成输出。给定python中的一些任意字符串变量(不是unicode),我想生成一个类似于 set s something 。。。这将把TCL变量“s”设置为精确的字符串,而不管其中有什么奇怪的字符。在不太奇怪的情况下,我不想让输出比需要的更混乱。我相信一个体面的方法是正确的 如果字符串不是空的,并且只包含字母数字和一些字符,如-(但绝对不是$“{}\),则可以按原样使用它 如果它只包含可打印字符,并且没有双引号或大括号(并且不
set s something
。。。这将把TCL变量“s
”设置为精确的字符串,而不管其中有什么奇怪的字符。在不太奇怪的情况下,我不想让输出比需要的更混乱。我相信一个体面的方法是正确的
-
(但绝对不是$“{}\
),则可以按原样使用它{}
\
转义符后,在其周围放置\
,{
}
$
[
]转义符,以及\nnn
转义符用于非打印字符我知道还有许多其他字符串可以被
{}
引用,但似乎很难轻易识别它们。另外,如果您不介意非打印字符(特别是换行符)出现在TCL输出中,那么看起来可以使用(2)。您实际上只需要2条规则
- 逃逸花括号
- 将输出用大括号括起来
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}]
subst
一些选项,则只需转义\
和{}
set s[subst-nocommands-novariables{$output}]
但是,您需要使用正则表达式将不可打印的字符转换为转义代码
祝你好运 要正确执行此操作,还应指定python字符串的编码,通常为sys.getdefaultencoding()。否则,在将其翻译为Tcl时,您可能会篡改编码 如果您的字符串中有二进制数据,并且希望得到Tcl二进制字符串,那么这将始终有效:
data = "".join("\\u00%02x" % ord(c) for c in mystring)
tcltxt = "set x %s" % data
看起来像一个十六进制转储,但好吧,这是一个十六进制转储
如果您使用任何特殊的编码,比如UTF-8,您可以通过使用convertfrom/convertto编码和适当的Python习惯用法来增强这一点
data = "".join("\\u00%02x" % ord(c) for c in myutf8string)
tcltext = "set x [encoding convertfrom utf-8 %s]" % data
当然,您可以对其进行一些改进,避免对所有非特殊字符进行\u编码,但上述操作在任何情况下都是安全的。Tcl在双引号字符串中包含的元字符非常少,所有这些元字符都可以通过在前面加反斜杠来引用。您必须引用的字符是
\
本身、$
和[
,但最好也引用]
、{
和}
,这样脚本本身就可以嵌入。(Tcl自己的list
命令可以做到这一点,除了它实际上没有包装双引号,因此它还可以处理反斜杠,并且它还将尝试在“nice”上使用其他技术。)字符串。有一种算法可以做到这一点,但我建议不要为代码的复杂性而烦恼;简单的通用规则更适合于正确的编码。)
第二步是将数据导入Tcl。如果要生成文件,最好的选择是将其写入UTF-8,并使用-encoding
选项tclsh/wish或source
命令来明确说明编码是什么。(如果您在同一进程中,请将UTF-8数据写入字符串,并对其进行求值。作业已完成。)该选项(在Tcl 8.5中引入)专门用于处理此类问题:
source -encoding "utf-8" theScriptYouWrote.tcl
如果不可能的话,你就不得不退回到添加额外的报价。最好的办法是假设您只有ASCII支持(一个很好的最低公分母),然后引用其他所有内容作为第一段中描述的引用的单独步骤。引用一下,将U+00080中的每个Unicode字符转换为形式为\uxxx
的转义序列,其中XXXX正好是四个十六进制数字[1],另外两个是文字字符。不要使用\xXX
表单,因为它有一些“令人惊讶的”错误特性(唉)
[1] Tcl中有一个关于处理基本多语言窗格之外的字符的公开错误,部分原因是
\u
表单无法处理。幸运的是,非BMP字符在实践中仍然相当罕见。但我发现:转义卷曲可以防止在查找匹配的结束卷曲时考虑它们,但反斜杠不会被删除(因为它们用于双引号),即结果仍然会有我添加到原始卷曲中的反斜杠。好的。。。我没有想到使用TCL命令来完成这项工作。但是看起来除了[]{}$-之外,我还需要转义反斜杠,所以它几乎与双引号的情况相同(但不需要转义)转义不可打印字符是我想做的事情,即使没有必要。对于不可打印字符\nnn是什么意思?@GaryWilloughby反斜杠后跟三个八进制数字是一种转义,可用于不可打印字符。我知道