TCL抓住特殊界限内的词语

时间:2014-02-17 09:40:08

标签: word tcl boundary

异议:获取“{”“}”边界内的所有单词。

input_file.txt:

set_false_path -from [get_ports {a/b[1] ab/cd_1 abcd_1_ad_}] -through [get_pins {th/th1 th2/th2[2]}]
set_derate -whatever [get_ports {xxx/xx1 xxx xxxx_1}]
set_false_path 3 -to [get_pins {aaa/d aaa/b}] -from [get_abc {abc/ac/dd nnn_2/2}]

预期output_file.txt:

a/b[1]
ab/cd_1
abcd_1_ad_
th/th1 
th2/th2[2]
aaa/d aaa/b
abc/ac/dd 
nnn_2/2

注意:可能有两对或更多对“{”“}”,我想在“{”和“}”中抓住所有这些单词,无论它们有多少。

这是我的代码:

set inputfile [open "input_file.txt" r]
set outputfile [open "output_file.txt" w]


while { [gets $inputfile line] != -1 } {
 set first_word [lindex [split $line ""] 0]
  if { regexp "set_false_path" $first_word} {
    # HOW TO grab all words between "{" and "}" ; split them ; put on output_file 
  }
} else {
}

close $inputfile
close $outputfile

3 个答案:

答案 0 :(得分:0)

由于您没有将行拆分为多行,因此您可以使用比previous script更简单的脚本:

set inputfile [open "input_file.txt" r]
set outputfile [open "output_file.txt" r]

while {[gets $inputfile line] != -1} {
  # If starts with set_false_path, process
  if {[lindex [split $line " "] 0] eq "set_false_path"} {

    # Grab each element with regexp into a list and print each to outputfile
    # m contains whole match, groups contains sub-matches
    foreach {m groups} [regexp -all -inline -- {\{([^\}]+)\}} $line] {

      # Trim any trailing/leading spaces
      set groups [string trim $groups]
      foreach out [split $groups] {
        puts $outputfile $out
      }
    }
  }

}

close $inputfile
close $outputfile

答案 1 :(得分:0)

我提交两种替代方法只是为了变化。

方法1:使用unknown处理程序

这是一种不同的方法:由于输入文件似乎是一个Tcl脚本,一旦我们检测到一行set_false_path,我们就可以评估该行以提取PIN。为了实现这一点,我们设置了一个名为unknown的过程来捕获所有未知过程。在这种情况下,我们对get_portsget_pinsget_abc ...:

感兴趣
# proc unknown is invoked for all unknown procedures: those that are
# called without previously defined.
proc unknown {cmdName args} {
    global outFile

    # List of procedures with PINs as arguments
    set pinProcs {get_ports get_pins get_abc}

    # If the procedure has PINs as arguments, we extract those PINs
    # and write to a file
    if {[lsearch -exact $pinProcs $cmdName] != -1} {
        eval "set args $args"; # Remove the surrounding braces {}
        foreach arg $args { puts $outFile $arg }
    }
}

set inFile  [open "input_file.txt"]
set outFile [open "output_file.txt" "w"]
while {[gets $inFile line] != -1} {
    if {[lindex [split $line " "] 0] eq "set_false_path"} {
        eval $line; # Tells Tcl interpreter to interpret the line
    }
}
close $inFile
close $outFile

这种方法有几个优点:它依赖于Tcl来正确解析输入行,我们不必处理凌乱的正则表达式。缺点包括需要手动跟踪我们感兴趣的程序(参见上面的pinProcs)。

方法2:创建我们自己的set_false_path程序

与上述类似,这一次,我们设置了自己的set_false_path程序来提取遵循以下标志的所有PIN:-to-from-through 。这种方法的优点是我们不必手动保留过程名称列表(参见pinProcs)。

# Our own proc, which returns a list of PINs
proc set_false_path {args} {
    set result {}
    for {set i 0} {$i < [llength $args]} {incr i} {
        set token [lindex $args $i]
        if {[lsearch -exact {-to -from -through} $token] != -1} {
            incr i
            set token [lindex $args $i]
            lappend result {*}[lindex $args $i]
        }        
    }
    return $result
}

# proc unknown is invoked for all unknown procedures: those that are
# called without previously defined.
proc unknown {cmdName args} {
    eval "set args $args"; # Remove the surrounding braces {}
    return $args
}

set inFile  [open "input_file.txt"]
set outFile [open "output_file.txt" "w"]
while {[gets $inFile line] != -1} {
    if {[lindex [split $line " "] 0] eq "set_false_path"} {
        foreach pin [eval $line] {
            puts $outFile $pin
        }
    }
}
close $inFile
close $outFile

答案 2 :(得分:0)

它正在运作!非常感谢你!你太棒了,老兄:)

这是我的最终代码:

set inputfile [open "input_file.txt" r]
set outputfile [open "output_file.txt" w]

set first_word ""
while { [gets $inputfile line != -1] } {
 if { ([lindex [split $line ""] 0] eq "set_false_path") } {
  foreach {m groups} [regexp -all -inline -- {\{(.+?)\}} $line] {
   foreach out [split $groups] {
    puts $outputfile $out
   }
  }
 }
}

close $inputfile
close $outputfile

input_file.txt:

set_false_path -from [get_ports {a/b[1] ab/cd_1 abcd_1_ad_}] -through [get_pins {th/th1 th2/th2[2]}]
set_derate -whatever [get_ports {xxx/xx1 xxx xxxx_1}]
set_false_path 3 -to [get_pins {aaa/d aaa/b}] -from [get_abc {abc/ac/dd nnn_2/2}]

output_file.txt(所有行的{}括号内的所有单词都以“set_false_path”开头):

a/b[1]
ab/cd_1
abcd_1_ad_
th/th1
th2/th2[2]
aaa/d aaa/b
abc/ac/dd 
nnn_2/2

这个论坛很棒!感谢你们! :)

祝你好运, 安迪李