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\""
第二个列表是一个元素的原因是因为我们用 ""
引用了 hello
和 world
这两个词,因此 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
命令)。提取元素(例如,使用 lindex
或 foreach
)并将正则表达式应用于该元素。
我在我的 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\""
第二个列表是一个元素的原因是因为我们用 ""
引用了 hello
和 world
这两个词,因此 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
命令)。提取元素(例如,使用 lindex
或 foreach
)并将正则表达式应用于该元素。