2013-12-12 18 views
1

我想提取error_name,嚴重性和發生次數。 這裏是我的報告的摘錄:我的正則表達式不起作用

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 
}       

但它不寫什麼。

回答

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 
+0

您可能希望在結尾處添加'close $ fid': – nurdglaw

+0

非常感謝。它的工作:) – tcluser16

+0

請您爲我的理解說明一下情況。謝謝! – tcluser16

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的開始,您將獲得更好的性能(因爲您可以更快地解析行並繼續到下一行),但如果這就是您的數據是,這就是你的數據。