TCL中list的行为

Behaviour of list in TCL

我在我的 TCL 代码中使用一个列表(只有一个元素),当我用 puts 打印它时,我发现文本有时用大括号括起来。例如:{abc} 有时不是。这会导致问题,因为我正在对这个特定文本执行 regsub 并且大括号导致我的代码失败。我还观察到,当文本中有特殊符号时,列表会用大括号括起来。 任何人都可以解释为什么列表用大括号括起来。

tcl 中的值与其他语言的工作方式不同。在 tcl 中,列表只是一个字符串。特殊格式的字符串。

列表

列表的规则看似简单:

A list is simply a string of words where each element of the list is a word separated by white space.

字数

上面"word"这个词是tcl对word的定义,不是正规的英文定义:

Whitespace separates words

这意味着单词是由白色分隔的连续字符串space。但我们还有另一个规则:

Words can be entirely enclosed in quotes to escape interpretation of whitespace

换句话说,在tcl代码中:

# The following is a word:
hello

# The following is also a word, ONE word, not two:
"hello world"

# The following are TWO words:
say "hello world"

列表示例

所以根据上面定义词的规则,下面是一个列表的例子:

# This is a list of two elements:
"hello world"

# This is a list of one element:
"\"hello world\""

第二个列表是一个元素的原因是因为我们用 "" 引用了 helloworld 这两个词,因此 tcl 解释器将其视为一个词。

行情

I see that the text is sometimes enclosed with braces 的答案来了。

在tcl中引用words/strings有两种方式:""{}。双引号像在 Perl 中一样工作,大括号像在 Perl 中一样工作。即,变量和函数在 "" 内代入,但不在 {}.

内代入

所以下面两个列表是完全等价的:

# List with one element:
{"hello world"}

# List with one element:
{{hello world}}

有趣的是,上面的两个列表也等同于:

# List with one element:
{hello\ world}

因为转义 space 字符强制 tcl 将其视为普通字符而不是单词分隔符。

从技术上讲,如果您尝试将列表视为字符串,则没有关于列表应该是什么样子的官方规范形式。因此,解释器可以根据需要自由插入 {}\""。所以不要将列表视为字符串。让 tcl 处理列表。

例如,为了避免正则表达式需要处理 {} 个字符,您应该使用列表操作来处理您想要的元素:

set l {}
lappend l "hello world"
regexp {hello} [lindex $l 0]

如果您需要搜索列表,请使用 lsearch 而不是 regexp:

lsearch -regexp $l {hello}

当 Tcl 从单个值创建列表时,它会尝试使用尽可能少的引号。如果它是像 abc 这样的简单值,它会忽略所有引号字符。如果它是一个带有像 space 这样的元语法字符的值 (abc def),它会将它括在大括号中 ({abc def})。如果它是 (abc{def) 中带有不平衡大括号的值,则使用反斜杠 (abc\{def)。这确保 Tcl 创建的列表始终也可以理解为包含单个命令的脚本,其单词恰好是列表的元素。

在列表上使用 regexp 不是一个好主意;这种格式对于那种工作来说并不是很友好(当你考虑所有可以 parsed 的东西时更糟糕的是一个列表,这比 Tcl 实际生成的要多得多来自 list 命令)。提取元素(例如,使用 lindexforeach)并将正则表达式应用于该元素。