TCL通过命令行传递正则表达式列表

时间:2013-04-06 01:29:16

标签: regex tcl command-line-arguments

我想使用命令行参数将正则表达式列表传递到我的TCL脚本中(目前使用的是TCL 8.4,但稍后将使用8.6)。现在,我的脚本有一个可选的标志,您可以设置名为-spec,后面跟着正则表达式列表。 (它还有一些其他可选标志。)

所以我希望能够从命令行执行此操作:

>tclsh84 myscript.tcl /some/path -someflag somearg -spec "(f\d+)_ (m\d+)_" 

然后在我的剧本中,我会有这样的事情:

set spec [lindex $argv [expr {[lsearch $argv "-spec"] + 1}]]
foreach item $spec {
    do some stuff
}

除了我传递正则表达式列表的部分之外,我有它的工作。上面的方法不适用于传递正则表达式...但是,如果没有引号,它的行为就像两个参数而不是一个,并且大括号似乎也不正常。有更好的解决方案吗? (我有点像新手......)

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

在解析命令行选项时,最简单的方法是将所有这些分开并将其转换为更容易在其余代码中使用的内容。也许是这样的:

# Deal with mandatory first argument
if {$argc < 1} {
    puts stderr "Missing filename"
    exit 1
}
set filename [lindex $argv 0]

# Assumes exactly one flag value per option
foreach {key value} [lrange $argv 1 end] {
    switch -glob -- [string tolower $key] {
        -spec {
            # Might not be the best choice, but it gives you a cheap
            # space-separated list without the user having to know Tcl's
            # list syntax...
            set RElist [split $value]
        }

        -* {
            # Save other options in an array for later; might be better
            # to do more explicit parsing of course
            set option([string tolower [string range $key 1 end]]) $value
        }

        default {
            # Problem: option doesn't start with hyphen! Print error message
            # (which could be better I suppose) and do a failure exit
            puts stderr "problem with option parsing..."
            exit 1
        }
    }
}

# Now you do the rest of the processing of your code.

然后你可以检查是否有任何RE符合这样的字符串:

proc anyMatches {theString} {
    global RElist
    foreach re $RElist {
        if {[regexp $re $theString]} {
            return 1
        }
    }
    return 0
}

答案 1 :(得分:0)

对每个模式使用一个-spec,如find,grep,sed等。

set indices [lsearch -all -regexp $argv {^-{1,2}spec$}]
if {[llength $indices] && [expr {[lindex $indices end] + 1}] >= $argc} {
    # bad use
}
foreach index $indices {
    set pattern [lindex $argv [incr index]]
    # ...
}