Tcl,如果不是不工作

时间:2017-12-18 21:30:54

标签: tcl

我试图做一个如果没有与Tcl匹配的字符串。但是,当我预计它不匹配时,它似乎是匹配的,因为当它不应该匹配时,它继续“#34;我不希望它这样做"。希望这是有道理的。在log.text文件中,它应该包含,"这是一个字符串。"

set var1 "String"
set file [open "log.text" r]

while {[gets $file data] != -1} {
   if {![string match *[string toupper $var1]* [string toupper $data]]} {
       *I don't want it to do this
   }
}

2 个答案:

答案 0 :(得分:1)

您的代码似乎工作正常:

$ cat log.text
This is a String
this line does not match
$ tclsh <<'END'
set var1 "String"
set file [open "log.text" r]

while {[gets $file data] != -1} {
   if {![string match -nocase *$var1* $data]} {
        puts "$data: does not match $var1"
   }                                      
}   
END

输出

this line does not match: does not match String

啊,现在你已经清楚地说明了你想要的东西:字符串在文件中,是或否。以下是实现这一目标的一些方法:

  1. 读取整个文件,并对其进行字符串匹配。

    set file [open log.text r]
    set contents [read -nonewline $file]
    close $file
    set pattern_exists [string match -nocase *$var1* $contents]
    if {$pattern_exists} {puts "$var1 found in file"}
    
  2. 逐行读取文件,直到找到模式

    set pattern_exists false
    set file [open log.text r]
    while {[gets $file line] != -1} {
        if {[string match -nocase *$var1* $line]} {
            set pattern_exists true
            break
        }
    }
    close $file
    if {$pattern_exists} {puts "$var1 found in file"}
    
  3. 调用grep来执行繁重的工作:当找不到模式时,grep以非零状态退出,exec认为非零退出状态是异常(请参阅{{ 3}})

    try {
        exec grep -qi $var1 log.text
        set pattern_exists true
    } on error {e} {
        set pattern_exists false
    }
    if {$pattern_exists} {puts "$var1 found in file"}
    

答案 1 :(得分:0)

你编写的代码 有效......但我猜它是其他东西的代理。如果您希望查看任意字符串是否作为一个行的子字符串存在,那么最好使用string first而不是string match,因为后者有一些元字符(尤其是[],表示一组字符),如果您不期待它们,可能会导致问题。

尝试:

if {[string first [string toupper $var1] [string toupper $data]] >= 0} {
    # The substring was there...
}

或者,在构建搜索模式时应用相关的反斜杠引用(可能使用string map)或使用regexp,这有一个有用的find-a-literal模式:

if {[regexp -nocase ***=$var1 $data]} {
    # The substring was there...
}

***=表示“此模式的其余部分是要匹配的文字字符串”,我们可以将-nocase作为选项传递,以便我们不需要使用string toupper。< / p>