为什么我的变量中的特殊字符在 TCL 中执行 lindex 时消失了?

Why does special characters in my variable disappear on doing an lindex in TCL?

我的应用程序中有一个我正在处理的列表。它基本上是这样的:

$item = {text1 text2 text3}

然后我选择列表中的第一个成员:

lindex $item 0

在执行此操作时,曾经(比如)abcdef345 的 text1 变为 abcdef12345。 但对我来说非常重要的是不要失去这个 \ 。为什么会消失。还有其他字符,如 -> 不会消失。请注意,我无法预先在文本中转义 \ 。如果在用lindex操作$item之前有什么我可以做的,请建议。

在 tcl 中,可以通过多种方式创建列表:

通过将变量设置为值列表

set lst {{item 1} {item 2} {item 3}} 

使用拆分命令

set lst [split "item 1.item 2.item 3" "."] 

使用列表命令。

set lst [list "item 1" "item 2" "item 3"] 

并且可以使用 lindex 命令访问单个列表成员。

set x "a b c"
puts "Item 2 of the list {$x} is: [lindex $x 2]\n"

这将给出输出:

Item 2 of the list {a b c} is: c

并且关于提出的问题 您需要像这样定义变量 abcdef\12345

为了弄清楚这一点,请尝试 运行 以下命令。

puts "\nI gave 0.00 to my daughter."

puts "\nI gave $100.00 to my daughter."

第二个会给你正确的结果。

如果您没有更改文本的选项,请尝试将文本保存在大括号中,如第一个示例中所述。

set x {abcd345}
puts "A simple substitution: $x\n"

输出:

A simple substitution: abcd345

set y [set x {abcdef345}]

并检查此输出:

puts "Remember that set returns the new value of the variable: X: $x Y: $y\n"

输出:

Remember that set returns the new value of the variable: X: abcdef345 Y: abcdef345

问题在于 \ 是一个 Tcl 列表元语法字符,不同于 -> 或任何字母数字。在使用 lindex (或任何其他使用列表的操作)之前,您需要将字符串转换为适当的 Tcl 列表。为此,您需要确切地理解输入数据中“单词”的含义。如果您的输入数据是由单个空白字符分隔的非空白字符序列,您可以使用 split 转换为列表:

set properList [split $item]
# Now we can use it...
set theFirstWord [lindex $properList 0]

如果您有不同的分隔符,split 会使用一个可选的额外字符来说明要分割的内容。 例如, 要用冒号 (:) 分割,您可以这样做:

set properList [split $item ":"]

但是,如果您有其他类型的拆分规则,则效果不佳。例如,如果您可以按 多个 空白字符拆分,实际上最好使用 regexp(使用 -all -inline 选项)来进行单词识别:

# Strictly, this *chooses* all sequences of one or more non-whitespace characters
set properList [regexp -all -inline {\S+} $item]

您也可以按多字符序列进行拆分,但在这种情况下,最容易的方法是先将多字符序列映射(使用 string map)到单个稀有字符。 Unicode 意味着有 lots 个这样的字符可供选择…

# NUL, \u0000, is a great character to pick for text, and terrible for binary data
# For binary data, choose something beyond \u00ff
set properList [split [string map {"BOUNDARY" "\u0000"} $item] "\u0000"]

甚至可能有更复杂的选项,但那是你使用 Tcllib 中的 splitx 时的情况。

package require textutil::split

# Regular expression to describe the separator; very sophisticated approach
set properList [textutil::split::splitx $item {SPL+I*T}]