TCL删除以字符开头的整行

时间:2016-11-09 11:50:15

标签: 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

但这只是删除了行开头的//符号,评论仍然存在。

3 个答案:

答案 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

文档: applyinterpnamespaceopenputssetunknown (object method)unknown