tcl中的正则表达式无法正常工作

时间:2013-09-20 18:14:35

标签: regex tcl

这件事正在扼杀我,我想我在tcl正则表达式中缺少非常基本的概念。我有以下代码

foreach line $data {
    if {[regexp {^(\#|\s)} $line]} {continue;} else {[lappend $puneet "$line"];}
}

所以我有变量行可能有'#'作为其第一个字符,或'\s'空格或正常的字母数字字符。现在我想要的是创建一个仅包含字母数字字符作为第一个字符的行列表。

但是上面的代码似乎没有给出所需的输出,因为我找不到一些语法问题。这是非常基本的,但由于我仍然是正则表达式的新手,我不确定我是否遗漏了上述表达式中的任何括号。

3 个答案:

答案 0 :(得分:5)

问题出在if声明的最后部分:

[lappend $puneet "$line"];

这将使用punneet变量的当前值的名称将行的匹配附加到变量。之后,它尝试查找一个具有当前行名称的命令,该命令可能会失败。

正确的是:

foreach line $data {
    if {[regexp {^(\#|\s)} $line]} {continue} else {lappend puneet $line}}
}

如果您使用的是Tcl 8.6,则可以将整个内容写为:

set puneet [lmap line $data {if {[regexp {^(\#|\s)} $line]} {continue}; set line}

答案 1 :(得分:3)

你的括号太多了!

foreach line $data {
    if {[regexp {^(\#|\s)} $line]} {continue;} else {[lappend $puneet "$line"];}
                                                  ;# ^                       ^ 
}

当您在$line

周围放置方括号时,您正在评估lappend

此外,对于lappend,您不应使用美元符号。

所有分号都可以放在这里:

foreach line $data {
    if {[regexp {^(\#|\s)} $line]} {continue} else {lappend puneet "$line"}
}

好的,现在有些内容可以更改一些:#不需要转义,您可以使用!来避免使用continue和{{1阻止和else并不需要在这里引用,因为它是唯一的参数:

$line

答案 2 :(得分:1)

我在这里使用lsearch而不是循环:

set data {{# one} two { three} #four five { six}}

set puneet [lsearch -all -inline -not -regexp $data {^(?:#|\s)}]    ;# two five