【问题标题】:TCL passing lists of regexes through command lineTCL 通过命令行传递正则表达式列表
【发布时间】:2013-04-07 03:39:01
【问题描述】:

我想使用命令行参数将正则表达式列表传递到我的 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
}

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

提前感谢您的帮助!

【问题讨论】:

    标签: regex tcl command-line-arguments


    【解决方案1】:

    在解析命令行选项时,最简单的方法是有一个简单的阶段将所有内容分开并将其转化为更易于在其余代码中使用的内容。可能是这样的:

    # 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
    }
    

    【讨论】:

    • 从 8.5 开始,其中一些事情可以做得更整洁一些(8.4 现在真的很老了),但这是一种技巧。
    • 非常感谢,我认为这比我以前的方法要好得多!
    【解决方案2】:

    每个模式使用一个 -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]]
        # ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-02
      • 2016-06-29
      • 1970-01-01
      • 1970-01-01
      • 2014-08-30
      • 2012-06-21
      • 1970-01-01
      • 2021-12-06
      相关资源
      最近更新 更多