2016-11-09 107 views
0

我有一個TCL腳本,從另一個文件中讀取一些數據開始整條生產線:TCL刪除所有以一個字符

#!/usr/bin/tclsh 
set config_params [open "file.vh" r] 
set file_data [read $config_params] 
close $config_params 

在文件中我讀(file.v)很少有整行被註釋掉例如:

//--------------------- 
// Comment 
// more comment 
// -------------------- 

// more comment 

我的問題是我如何擺脫開始王氏//並刪除空行中的所有行的?我已經使用regsub如下:

regsub -all -line "//" $file_data "" file_data 

但這只是刪除了// SIGN在該行的開頭和註釋仍然存在。

回答

0

設法做到這一點是:

regsub -all -line "//(.*)\n" $file_data "" file_data 
1

tl; dr:使用此RE(由於Tcl元字符在大括號中):{(?:^[ \t]*|//.*)(?:\n|\Z)}並考慮這是否是正確的方法。


OK,你在線路匹配模式,所以實際刪除線,你需要把\n到包括EOL標記。和需要還包括\Z(這是像一個超$用於線匹配模式)作爲在殼體的最後一行沒有終止的替代方案。然後,以匹配數據,你需要兩種可能的情況下,其餘的:要麼是有什麼,但空格就可以了,從開始到結束,或//後跟任意字符線(除換行;我們本着匹配模式)。一些非捕獲組織和交替包裝整個事情。

set data "abc 

def 
// ghi 
jk 

// lm 
nopq" 
puts [regsub -all -line {(?:^[ \t]*|//.*)(?:\n|\Z)} $data ""] 

產生這樣的輸出:

 
abc 
def 
jk 
nopq 

我不知道該RE是你真正想要的(你可能要更有選擇性有關注釋行去除規則),但它的工作原理具有合理的樣本情況。在我自己的代碼中,我可能先處理文本,先分割成幾行,然後使用更簡單的RE;對我來說更明顯是正確的,而不是使用複雜的RE,而每次我不得不多想一想它是否在做正確的事情。 RE怪物通常是一個壞主意,可維護性。

0

此代碼:

set int [interp create] 
$int eval {namespace delete ::} 
$int alias // apply {args {}} 
$int alias unknown apply {args {puts $args}} 

隨後調用

$int eval $file_data 

打印空行和文件的內容開始與「/ /」刪除(但見下文)。

如果你想輸出去一個文件,使用這樣的:

set f [open whatever w] 
$int alias unknown apply {{f args} {puts $f $args}} $f 

此代碼創建一個從解釋器,從中取出所有命令,然後給它兩個命令:在//命令由//開始的行執行(但不是以//---開頭的行...)並且什麼也不做,而unknown命令由所有其他行執行並打印該行。

最嚴重的限制是每行都根據Tcl命令語法進行分析,因此需要對花括號和括號進行平衡,括號會觸發命令替換,$ triggers變量替換等。對於帶有註釋的行的文本數據,可以做得好,但對於C++來說,它可能不會。

但是,這通過一個好的文本編輯器可以更好地處理。例如。 g/\v(^\s*\/\/|^$)/d在Vim。

文檔: applyinterpnamespaceopenputssetunknown (object method)unknown

相關問題