2013-04-06 69 views
1

我想使用命令行參數將正則表達式列表傳遞到我的TCL腳本(當前使用TCL 8.4,但將在以後使用8.6)。現在,我的腳本有一個可選標誌,您可以將其設置爲-spec,它的後面跟着正則表達式列表。 (而且它有一些其他可選的標誌也是如此。)TCL通過命令行傳遞正則表的列表

因此,這裏是諸如此類的事情,我希望能夠在命令行中執行:

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

我有它的工作,除了我傳遞的正則表達式列表中的部分。上述方法不適用於傳遞正則表達式......但是,如果沒有引號,它就像兩個參數而不是一個參數,並且大括號似乎也不能正確工作。有更好的解決方案嗎? (我是一個新手...)

在此先感謝您的幫助!

回答

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 
} 
+0

有些事情可以做多一點整齊地從8.5起(8.4現在是真的很老),但那很有趣。 – 2013-04-06 11:59:34

+0

非常感謝,我認爲這是一種比我更好的方法! – KaleidoEscape 2013-04-08 18:02:34

0

每個模式使用一個規格,如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]] 
    # ... 
}