2013-03-23 52 views
2

我有一個包裝線的文件。它恰好是包裝多行的TCL代碼。 (但它可以是任何東西,作爲換行的規則。)閱讀包裝線

,如:

set long [ some cmd { some long stuff \ 
    more stuff \ 
    even more stuff \ 
    end of cmd} but going on \ 
    end of set ] 

我想解析到一個單一的線,這樣我可以做一些圖案匹配它。

我看着文檔的「讀」命令,但似乎並沒有做到這一點。

非常感謝您的幫助。

感謝, 格特

回答

0

你可以看到的Tcl如何處理的論點很簡單:如果你想這一切作爲一個字符串

proc some {args} { 
    foreach arg $args { 
     puts $arg 
    } 
} 
set long [ some cmd { some long stuff \ 
    more stuff \ 
    even more stuff \ 
    end of cmd} but going on \ 
    end of set ] 

結果

cmd 
some long stuff more stuff even more stuff end of cmd 
but 
going 
on 
end 
of 
set 

,然後「有些CMD」 很簡單

proc some args {join $args} 
set long [some cmd ...] 
puts $long 

輸出

cmd some long stuff more stuff even more stuff end of cmd but going on end of set 
0

如果你有足夠的內存整個文件:

foreach line [split [regsub -- "\n\$" [regsub -all -- "\\\\\n\[\[:blank:\]\]*" [read stdin] " "] ""] "\n"] { 
    # ... 
} 

這並不相同\換行符替換爲Tcl的一樣。

1

我不是很有經驗的Tcl程序員,所以我的提議非常直截了當。

從你的問題我想,你逐行讀取文件中的行(我猜使用「獲取」),然後做行(模式匹配)的東西。所以,最直接forwart實施將是這樣的(順便說一下,其中一個問題是你喜歡尾隨「前面的」行的空格和領先的「下一個」行空格做什麼):

;# Note: The code bellow was not tested, and may not run cleanly, 
;# but I hope it shows the idea. 

;# Like "gets", but concatenates lines, which finish with "\" character with 
;# the next one. 
proc concatenatingGets {chan} { 
    set wholeLine "" 
    set finishedReadingCurentLine no 

    while {! $finishedReadingCurrentLine } { 

     set currentLine [gets $chan] 

     ;# more complicated rule can be used here for concatenation 
     ;# of lines 

     if {[string index $currentLine end] == "\\"} { 

      ;# Decide here what to do with leading and trailing spaces. 
      ;# We just leave them as is (only remove trailing backslash). 
      ;# Note, that Tcl interpreter behaves differently. 

      append wholeLine " " [string range $currentLine 0 end-1] 

     } else { 

      set finishedReadingCurrentLine yes 

     } ;# if-else strig is to be concatenated 

    } ;# while ! finishedReadingcurrentLine 

} ;# concatenatingGets 

;# Now use our tweaked gets: 
set f [open "myFileToParse.txt" r] 
while {![eof $f]} { 
    set currentLine [concatenatingGets $f] 

    ;# ... Do pattern matching ot current line, and whatever else needed. 

} 
close $f 
1

由於您正在閱讀Tcl代碼,因此可以使用Tcl提供的幫助。特別是,info complete會說一個字符串是否包含一個「complete」命令,這對於檢測連續行和多行文字(例如過程體)非常有用。關於它的唯一技巧是,只有當你把換行符也放入時,所有東西才能正常工作。因此:

set buffer {} 
set fd [open $thefilename] 
# Next line is idiomatic "read by lines" pattern 
while {[gets $fd line] >= 0} { 
    append buffer \n $line 
    # IMPORTANT: need extra newline at end for this to work with 
    # backslash-newline sequences. 
    if {![info complete $buffer\n]} { 
     # Get next line 
     continue 
    } 
    processACompleteCommand $buffer 
    set buffer {} 
} 
close $fd 
# Deal with the last command if necessary (EOF is always a command terminator) 
if {$buffer ne ""} { 
    processACompleteCommand $buffer 
} 
+0

酷。我會給+1顯示習慣用法的表達式,+1用來顯示如何使用Tcl來處理Tcl代碼(不幸的是我只能給出一個+1)。 – 2013-03-25 05:40:16