0

我正在尝试使用{*}TCL 脚本中的正则表达式将名称与其自身加上可能的后缀进行匹配。例如:

#!/usr/bin/tclsh
set name "g_renamed_d"
set pattern "g_renamed*"
if {  [string match "$name" "$pattern"]} {
    puts " matched!" 
} else {
    puts " not matched!!!!!"
}

当这不起作用时,我尝试从模式变量中删除星号并使用[string match "$name" "$pattern"*][string match $name $pattern*][string match $name {$pattern*}]但都无济于事。我已经看到了与我所做的相同的其他示例;我错过了什么?

4

3 回答 3

4

您可以尝试使用以下语法:

#!/usr/bin/tclsh
set name "g_renamed_d"
set pattern "^g_renamed.*"
if {[regexp $pattern $name match]} {
    puts " matched! :)" 
    puts $match
} else {
    puts " not matched! :("
}

请注意,上面的模式允许所有类型的字符,包括除换行符之外的空格。如果您想要一个更“合理”的模式,您可以将逗号替换为带有您在后缀中允许的字符的字符类:

set pattern "^g_renamed[a-z0-9_]*" # all "word" character (the same as \w)

或者

set pattern "^g_renamed\S*"    # all that is not a white space

但是,如果您只想检查字符串是否以目标开头,则此模式就足够了:

set pattern "^g_renamed"
于 2013-07-11T19:12:40.720 回答
4

您正在将glob-style 星号与正则表达式 (Kleene) 星号混合。

在正则表达式中,*并不意味着“任何字符的字符串”,如glob-style 用法中的情况。*, +, 和?都称为量词,分别表示前面原子(字符)的“0 或更多”、“1 或更多”和“0 或 1”重复。

因此,例如,*它本身什么也不做,而是a*匹配 0 个或多个as。

要匹配 0 个或多个任何内容,您需要在通配符上放置一个量词,在正则表达式中是.,意思是“除换行符之外的任何字符”。这就是为什么,正如@CasimiretHippolyte 首先在他的回答中指出的那样,你想要g_renamed.*.

此外,匹配的工作方式是,如果模式匹配字符串中的任何位置regexp,它就会返回。也就是说,名字,也会过去的!这就是@CasimiretHippolyte 建议使用锚点的地方,它与字符串的开头匹配,模式锚定到字符串的开头。(类似地,是另一个锚点,这个锚点匹配字符串的结尾。)truefoog_renamedbar^$


顺便说一句,如果你真的想要glob-style 匹配,那么使用string match.

于 2013-07-11T19:23:41.477 回答
0

你做反向比较。只需更改内容即可。喜欢触发;tcl;

eval {
    set pattern "g_renamed_d"
    set name "g_renamed*"
    if { [string match -nocase "$name" "$pattern"] } {  
        puts " matched!" 
    } else {
        puts " not matched!!!!!"
    }       
}
于 2014-09-18T06:43:59.743 回答