向 TCL 列表的元素添加额外的反斜杠
Adding an additional backslash to elements of TCL list
我有一个如下所示的列表:
list1 = {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
当我使用 foreach 循环一个一个 对列表的元素进行操作时:
`foreach ele $list1 {
puts "$ele
}`
我得到以下输出:
a.b.c.d
a.bb.ccd[0]
a.bb.ccd[1]
观察到,反斜杠丢失(由于 tcl 语言流)。
为了保持相同,我想向 list1 中具有现有反斜杠的所有元素添加一个额外的反斜杠。
我试过了:
regsub -all {\} $list1 {\} list1
(还尝试了双引号而不是大括号和其他可能的试验)。
似乎没有任何效果。
有没有办法确保 $ele 在 foreach 循环中保留反斜杠字符,因为我需要具有完全相同字符的元素以进行进一步处理。
P.S。初学者 regexp/regsub
正如您所定义的那样 list1
它是一个字符串。当 list1
与 foreach
命令一起使用时,字符串将转换为列表。请记住,Tcl 中的列表实际上只是特殊格式的字符串,在从字符串转换为列表时会对其进行解析。当列表元素被解析时,反斜杠根据正常的 Tcl 解析规则被移除。有几种方法可以构建包含对 Tcl 解析器重要的字符的列表。下面的代码显示了与您的代码对比的两个示例:
set list1 {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]}
puts "list1 as a string"
puts $list1
puts "converting the list1 string to a proper list"
foreach ele $list1 {
puts $ele
}
set list2 [list a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}]
puts "list2 build by the list command"
puts $list2
puts "list2, element by element"
foreach ele $list2 {
puts $ele
}
set list3 {a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}}
puts "list3 build properly quoting each element"
puts $list3
puts "list3, element by element"
foreach ele $list3 {
puts $ele
}
运行 这会产生:
list1 as a string
a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]
converting the list1 string to a proper list
a.b.c.d
a.bb.ccd[0]
a.bb.ccd[1]
list2 build by the list command
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list2, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
list3 build properly quoting each element
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list3, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
如果您将每个反斜杠替换为两个反斜杠,您的 regsub
尝试将会成功,但正确构建列表会更加清晰。
如果您的输入数据中有您希望保留的反斜杠,则在将该数据转换为 Tcl 列表时需要做一些额外的工作,否则 Tcl 将简单地假设您使用的是常规的反斜杠Tcl 元字符。有几种方法可以做到;这是我个人最喜欢的,因为它在逻辑上准确地选择了我们想要的字符(非空白的非空序列):
set input {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
set items [regexp -all -inline {\S+} $input]
foreach item $items {
puts $item
}
从输出中可以看出:
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
....
这样可以准确保留反斜杠。 (另外,是的,我很喜欢正则表达式。尤其是像这样非常简单的。)
我有一个如下所示的列表:
list1 = {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
当我使用 foreach 循环一个一个 对列表的元素进行操作时:
`foreach ele $list1 {
puts "$ele
}`
我得到以下输出:
a.b.c.d
a.bb.ccd[0]
a.bb.ccd[1]
观察到,反斜杠丢失(由于 tcl 语言流)。
为了保持相同,我想向 list1 中具有现有反斜杠的所有元素添加一个额外的反斜杠。
我试过了:
regsub -all {\} $list1 {\} list1
(还尝试了双引号而不是大括号和其他可能的试验)。
似乎没有任何效果。
有没有办法确保 $ele 在 foreach 循环中保留反斜杠字符,因为我需要具有完全相同字符的元素以进行进一步处理。
P.S。初学者 regexp/regsub
正如您所定义的那样 list1
它是一个字符串。当 list1
与 foreach
命令一起使用时,字符串将转换为列表。请记住,Tcl 中的列表实际上只是特殊格式的字符串,在从字符串转换为列表时会对其进行解析。当列表元素被解析时,反斜杠根据正常的 Tcl 解析规则被移除。有几种方法可以构建包含对 Tcl 解析器重要的字符的列表。下面的代码显示了与您的代码对比的两个示例:
set list1 {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]}
puts "list1 as a string"
puts $list1
puts "converting the list1 string to a proper list"
foreach ele $list1 {
puts $ele
}
set list2 [list a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}]
puts "list2 build by the list command"
puts $list2
puts "list2, element by element"
foreach ele $list2 {
puts $ele
}
set list3 {a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}}
puts "list3 build properly quoting each element"
puts $list3
puts "list3, element by element"
foreach ele $list3 {
puts $ele
}
运行 这会产生:
list1 as a string
a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\]
converting the list1 string to a proper list
a.b.c.d
a.bb.ccd[0]
a.bb.ccd[1]
list2 build by the list command
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list2, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
list3 build properly quoting each element
a.b.c.d {a.bb.ccd\[0\]} {a.bb.ccd\[1\]}
list3, element by element
a.b.c.d
a.bb.ccd\[0\]
a.bb.ccd\[1\]
如果您将每个反斜杠替换为两个反斜杠,您的 regsub
尝试将会成功,但正确构建列表会更加清晰。
如果您的输入数据中有您希望保留的反斜杠,则在将该数据转换为 Tcl 列表时需要做一些额外的工作,否则 Tcl 将简单地假设您使用的是常规的反斜杠Tcl 元字符。有几种方法可以做到;这是我个人最喜欢的,因为它在逻辑上准确地选择了我们想要的字符(非空白的非空序列):
set input {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
set items [regexp -all -inline {\S+} $input]
foreach item $items {
puts $item
}
从输出中可以看出:
a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....
这样可以准确保留反斜杠。 (另外,是的,我很喜欢正则表达式。尤其是像这样非常简单的。)