我有一个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
但这只是删除了行开头的//符号,评论仍然存在。
答案 0 :(得分:1)
tl; dr:使用此RE(由于Tcl元字符而在大括号中):{(?:^[ \t]*|//.*)(?:\n|\Z)}
并考虑这是否是正确的方法。
好的,您处于行匹配模式,因此要实际删除需要放置\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怪物通常是一个坏主意,可维护性。
答案 1 :(得分:0)
管理如下:
regsub -all -line "//(.*)\n" $file_data "" file_data
答案 2 :(得分: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
此代码的工作原理是创建一个从属解释器,从中删除所有命令,然后给它两个命令://
命令由以//
开头的行执行(但不是以{开头的行) {1}} ...)并且什么都不做,而//---
命令由所有其他行执行并打印该行。
最严重的限制是根据Tcl命令语法解析每一行,因此需要平衡大括号和括号,括号触发命令替换,$触发变量替换等。对于带有注释掉的行的文本数据,它可能很好工作,但对于C ++源代码,它可能会赢得
。然而,好的文本编辑器可以更好地处理这个问题。例如。 Vim unknown
。
文档: apply, interp, namespace, open, puts, set, unknown (object method), unknown