Regex 在tcl中匹配正则表达式{*}

Regex 在tcl中匹配正则表达式{*},regex,tcl,Regex,Tcl,我正在尝试使用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 ma

我正在尝试使用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*}]
但都没有效果。我见过其他的例子,它们似乎与我所做的相同;我缺少什么?

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

#!/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"

您将
glob
样式的星型与正则表达式(Kleene)星型混为一谈

在正则表达式中,
*
并不意味着“任何字符的字符串”,就像
glob
风格的用法一样
*
+
都被称为量词,分别表示前面原子(字符)的“0或更多”、“1或更多”和“0或1”重复

因此,例如,
*
本身没有任何作用,但
a*
匹配0或更多
a
s

要匹配0或更多的任何内容,您需要在通配符上放置一个量词,在正则表达式中,该通配符是
,意思是“除换行符以外的任何字符”。这就是为什么@CasimiretHippolyte在其回答中首先指出,您需要重命名
g_.

另外,
regexp
匹配的工作方式是,如果模式匹配字符串中的任何位置,它将返回
true
。也就是说,名称,
foog_renamedbar
也将通过!这就是@casimirithippolyte建议使用锚定
^
,它匹配字符串的最开始,即模式锚定到字符串的开始。(类似地,
$
是另一个锚点,该锚点与字符串的末尾匹配。)



顺便说一句,如果你真的想要
glob
-风格匹配,那么使用。

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


字符串匹配选项的语法是?模式字符串。Regex是另外一种东西,它使用regexp模式字符串?匹配?submatch1。。。如果变量本身是一个变量,则不需要在其周围加引号。因此
字符串匹配-nocase$name$pattern
非常好。为什么
eval
set pattern "^g_renamed"
eval {
    set pattern "g_renamed_d"
    set name "g_renamed*"
    if { [string match -nocase "$name" "$pattern"] } {  
        puts " matched!" 
    } else {
        puts " not matched!!!!!"
    }       
}