如何在tcl中准确复制?

如何在tcl中准确复制?,tcl,Tcl,我使用以下方法创建了一个列表: set list1 { o\\/one o\\/two o\\/three } 现在我想通过向每个项目添加{},将此列表复制到另一个列表 我的新名单应该是: { {o\\/one} {o\\/two} {o\\/three} } 我试着用 foreach a $list1 { set x "{$a}" append new_list " " "{$a}" lappend new

我使用以下方法创建了一个列表:

set list1 { o\\/one o\\/two o\\/three }
现在我想通过向每个项目添加{},将此列表复制到另一个列表 我的新名单应该是:

{ {o\\/one} {o\\/two} {o\\/three} }
我试着用

foreach a $list1 {
    set x "{$a}"
    append new_list " " "{$a}"
    lappend new_list1 $x
}
newlist
→ <代码>{o\/one}{o\/two}{o\/three}
newlist1
→ <代码>{o\/one}{{o\/two}{{o\/two}}


请提供帮助?

您的原始列表中包含以下项目(您可以使用
lindex
进行验证):

  • put[lindex$list1 0]
    → <代码>o\/one
  • put[lindex$list1]
    → <代码>o\/two
  • put[lindex$list1 2]
    → <代码>o\/three
  • 任何包含这些元素的列表,无论如何编码,都是成对的。列表的规范形式(由Tcl自己的列表操作生成)是:

    {o\/one}{o\/two}{o\/three}

    也许最简单的方法是:

    set list2 [lrange $list1 0 end]
    
    lrange
    命令使用Tcl的标准列表字符串引擎(与许多其他命令共享)。更喜欢不添加大括号,但更喜欢添加大括号而不是添加反斜杠;反斜杠是最后的选择,因为它们很难看,很难阅读。但它可以处理元素中的任意内容;盲目地添加大括号很容易受到棘手的边缘情况的影响

    获取上述规范形式的另一种方法是这样的(前提是您没有停留在Tcl的旧版本上,它们不再受支持):


    [编辑]:如果您有一个字符串,其中的某些内容用空格分隔,则可能需要将其转换为适当的列表;当输入数据包含列表元字符(如大括号和(在本例中相关的)反斜杠)时,这尤其有用。有两种主要方法可以做到这一点:

  • 设置列表[拆分$inputString]
  • 设置列表[regexp-all-inline{\S+}$inputString]
  • 当输入字符串的两个单词之间有两个(或更多)空格时,它们的不同之处在于:

    set inputString "a b  c d";                    # NB: two spaces between b and c
    puts [split $inputString];                     # ==> a b {} c d
    puts [regexp -all -inline {\S+} $inputString]; # ==> a b c d
    

    两者都有使用案例。

    我认为这是一个XY问题:你认为你可以通过添加大括号来解决你的问题,所以你在问怎么做。我觉得你原来的问题可以用更直接的方式解决。你能走一步吗。回过头来描述你试图解决的问题。我确实理解你的观点。我无法理解的是,当我在做
    放置$list1
    时,它正在打印
    o\\/one\\/two\\/three
    ,但当我打印单个列表项时,它会打印
    o\/one
    ,在另一个列表中复制时,有没有一种方法可以保留反斜杠,并在其中添加大括号有一个字符串,其中有些东西用空格分隔,而不是正式的Tcl列表
    split
    it(或者使用
    regexp-all-inline{\S+}
    ,如果有多个空格分隔符)将其转换为真正的Tcl列表。然后,你说出的单词将是你期望的单词(尽管整个列表可能与你期望的不一样)。
    set inputString "a b  c d";                    # NB: two spaces between b and c
    puts [split $inputString];                     # ==> a b {} c d
    puts [regexp -all -inline {\S+} $inputString]; # ==> a b c d