将 regsub 应用于 tcl 段落中的特定行

apply regsub for certain line in a paragraph in tcl

这是我分配给测试变量的行组

    set test {tkt(pnr(
                    ticket(20140414,130559),
                    fbcode(y),
                    etkt(yes),
                    entry(price),
                    trap([flist,186,tkt1,bag],[start(1)]),
                    city(y)
            ])).}

我需要从 "trap([flist,186,tkt1,bag]".

中的“trapremlist”变量中搜索一些值列表
    set trapremlist {bag bagdisclosure bt}

如果 trapremlist 中的任何值存在于 "trap([flist,186,tkt1,bag]" 中。然后我需要删除相同的。在这种情况下,我需要删除 "bag".

我想提取 trap([] 中的列表,并使用 lsearch 删除 trapremlist 中存在的值。

但是我无法在陷阱中获取列表([]并在解析后更新列表

你能建议最好的处理方法吗?

谢谢..

“廉价破解”方法是使用 string map:

set mapping {}
foreach value $trapremlist {
    # Sneaky point: remove version with leading comma first
    lappend mapping ",$value" "" $value ""
}
set removed [string map $mapping $test]

如果您在其他任何地方的删除列表中有任何单词,这将非常糟糕。如果是这种情况,您必须进行解析和重构。幸运的是,在这种情况下,我们可以逐行执行此操作:

set result {}
foreach line [split $test "\n"] {
    if {[regexp {^(\s*trap\(\s*\[)([\w,]+)(\].*\)\s*),\s*$} $line -> a b c]} {
        set b2 {}
        foreach bit [split $b ","] {
            if {$bit ni $trapremlist} {
                lappend b2 $bit
            }
        }
        set line $a[join $b2 ","]$c
    }
    lappend result $line
}
set removed [join $result "\n"]

如果你有一个真正的解析器在工作(tcllib 中有一个解析器生成引擎),你可以进行更全面的解析,但如果像上面这样简单的东西就足够好了,那就需要做很多工作。