我的正则表达式无效

时间:2013-12-12 01:23:00

标签: regex tcl

我想提取error_name,Severity和Occurrences。 以下是我的报告摘要:

error_name: xxxxxxxxxx
Severity: Warning Occurrence: 2 
error_name2:xxxxxxxxxxx. 
Severity: Warning Occurrence: 16 
error_name3:xxxxxxxxxxxxx 
Severity: Warning Occurrence: 15

我正在尝试

while { [ gets $fp line ] >= 0 } {
    if { [ regexp {^([^:\s]):.+^Severity:\s+Warning\s+Occurrence:\s+\d+} $line match errName count] } {
        puts $errName
        puts $count
        incr errCount $count
}                        

但它没有写任何东西。

2 个答案:

答案 0 :(得分:0)

我会这样写:

set fid [open filename r]
while {[gets $fid line] != -1} {
    foreach {match label value} [regexp -inline -all {(\w+):\s*(\S*)} $line] {
        switch -exact -- $label {
            Severity   {set sev $value}
            Occurrence {set count $value}
            default    {set err $label}
        }
    }
    if {[info exists err] && [info exists sev] && [info exists count]} {
        puts $err
        puts $count
        incr errCount $count
        unset err count sev
    }
}
puts $errCount
error_name
2
error_name2
16
error_name3
15
33

答案 1 :(得分:0)

如果你可以将整个文件同时保存在内存中(取决于你有多少内存相对于你有多少内存),那么你可以使用一个聪明的RE技巧来挑选所有内容:

# Load the whole file into $data
set f [open $filename]
set data [read $f]
close $f

# Store the RE in its own variable for clarity
set RE {^(\w+):.*\nSeverity: +(\w+) +Occurrence: +(\d+)$}
foreach {- name severity occur} [regexp -all -inline -line $RE $data] {
    # Do something with each thing found
    puts "$name - $severity - $occur"
}
好的,现在来解释一下。关键是我们一次解析整个字符串,但我们使用-line选项,以便^$成为行锚,.赢了不符合换行符。除此之外,-all -inline执行它所说的内容:返回找到的所有内容,匹配项和子匹配项的列表。然后我们用foreach迭代它(-是一个奇怪的变量名,但它对于“虚拟丢弃”很方便)。这使得大多数复杂的字符串解析保留在RE引擎中,而不是尝试在脚本中执行操作。

如果你可以比“从行开始的单词开始”更好地限制RE的开始,你将获得更好的性能(因为你可以更快地解析一行并继续下一行)但是如果这就是你的数据是什么,这就是你的数据。