动态地向命令添加标志

时间:2014-01-02 09:15:16

标签: tcl

是否可以动态地向命令添加标志,而不使用eval

例如,我希望使用变量执行以下操作:

set isCaseSensitive 1
if {$isCaseSensitive == 1} {
    set res [regexp -nocase -- $regexp $str]
} else {
    set res [regexp -- $regexp $str]
}

# The following does NOT work

set regexp_flags ""
if {$isCaseSensitive == 1} {
    append regexp_flags " -nocase"
}
set res [regexp $regexp_flags -- $regexp $str]

使用Tcl 8.5


编辑#1,12:41 UTC:
(对评论员Jerry的回应)

我已经执行了代码:

set regexp_flags ""
if {$isCaseSensitive == 1} {
    append regexp_flags "-nocase"
}

set res [regexp -line -all -inline -indices $regexp_flags -- $regexp $str]

并收到以下错误(省略不相关的文字):

regexp match variables not allowed when using -inline
    while executing
"regexp -line -all -inline -indices $regexp_flags -- $regexp $str"

这是因为Tcl认为$str是第4个参数,在使用-inline标志时禁止使用。{/ p>

请参阅regexp command documentation


编辑#2,14:01 UTC:

显然由于某种原因,我的主题字符串($str)中的不可打印字符对此命令有一些负面影响。 (Tcl不受二进制保护或其他什么?)
我在尝试regexp之前尝试删除这些字符,现在它按预期工作。

set regexp_flags ""
if {$isCaseSensitive == 1} {
    append regexp_flags "-nocase"
}

set str [regsub -all -- {[^[:print:]\t\n\r\f\v]} $str ""]
set res [regexp -line -all -inline -indices $regexp_flags -- $regexp $str]

1 个答案:

答案 0 :(得分:1)

在8.5和8.6中,最好的办法是:

set regexp_flags ""
if {$isCaseSensitive == 1} {
    lappend regexp_flags -nocase
}

set res [regexp -line -all -inline -indices {*}$regexp_flags -- $regexp $str]

在8.4(之前,如果你真的旧学校!)你需要这种结构(你肯定需要第二个[list …]因为RE和字符串不太可能是简洁的单词):

set regexp_flags ""
if {$isCaseSensitive == 1} {
    lappend regexp_flags -nocase
}

set res [eval [list regexp -line -all -inline -indices] $regexp_flags [list -- $regexp $str]]

虽然这可能写得更好:

set regexp_cmd [list regexp -line -all -inline -indices]
if {$isCaseSensitive == 1} {
    lappend regexp_cmd -nocase
}

set res [eval $regexp_cmd [list -- $regexp $str]]
你不宁愿使用8.5吗?或者将(?i)放在RE的前面(这也使它不区分大小写)?