在TCL列表

时间:2018-05-16 00:26:13

标签: tcl backslash regsub

我有一个类似的列表:

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

2 个答案:

答案 0 :(得分:1)

如果你的输入数据中有反斜杠,就像你希望保留的那样,你需要在将数据转换为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\]
....

这样可以保持反斜杠。 (另外,是的,我非常喜欢正则表达式。特别是非常简单的表达式。)

答案 1 :(得分:0)

正如您已定义list1,它是一个字符串。当list1foreach命令一起使用时,字符串将转换为列表。请记住,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尝试将起作用,但正确构建列表会更清晰。