为什么我的变量中的特殊字符在 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}]
我的应用程序中有一个我正在处理的列表。它基本上是这样的:
$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}]