Regex 在提到的一行之后接一行

Regex 在提到的一行之后接一行,regex,tcl,Regex,Tcl,输入: 等等 输出: @@@@@@@@@@@@@@ my_data1 12 23 34 my_data2 10 23 4 my_data3 1 2 34 my_data4 12 3 3 我想让我的Tcl代码查找第1行表达式,即以@^@开头,然后只打印下一行。下面是代码,通过逐行读取文件来完成您需要的操作 my_data1 12 23 34 最简单的方法是读取中的所有数据并使用合适的lsearch 那是假设你想要一行以@开头的所有行。要获得第一个: set f [open $filename

输入:

等等

输出:

@@@@@@@@@@@@@@
my_data1 12 23 34
my_data2 10 23 4
my_data3 1 2 34
my_data4 12 3 3 

我想让我的Tcl代码查找第1行表达式,即以@^@开头,然后只打印下一行。

下面是代码,通过逐行读取文件来完成您需要的操作

my_data1 12 23 34

最简单的方法是读取中的所有数据并使用合适的lsearch

那是假设你想要一行以@开头的所有行。要获得第一个:

set f [open $filename]
set lines [split [read $f] "\n"]
close $f

set matched [lsearch -all -regexp $lines {^@}]

foreach idx $matched {
    puts [lindex $lines [expr {$idx + 1}]]
}

也就是说,没有全部和循环的结果,而不是检查我们没有得到-1记录的不匹配指标。

其他解决方案是好的,但可能有点太复杂了。为了提供一些对比:

set idx [lsearch -regexp $lines {^@}]
if {$idx >= 0} {
    puts [lindex $lines [expr {$idx + 1}]]
}
这假设in的值是一个为读取而打开的通道,它可以是stdin,也可以是一个打开的文件

背后的逻辑是:读一行;如果匹配,再读一行并打印,然后退出。重复此操作,直到输入用尽

ETA:如果一行代码很难直观地解析,那么在更多行中也有同样的情况:

while {![eof $in]} { if {[regexp {^@} [gets $in]]} { puts [gets $in] ; break } }

这样写会使结构更加清晰,但是这个解决方案基本上是一行程序,真的。

请添加您用来读取文件的代码。输入是一个列表还是一个文件?通过指定它,您已经完成了大部分工作:-请参阅以及和。为了使代码尽可能清晰,我通常避免编写一行程序;代码高尔夫属于其他地方:-
while {![eof $in]} { if {[regexp {^@} [gets $in]]} { puts [gets $in] ; break } }
while {![eof $in]} {
    if {[regexp {^@} [gets $in]]} {
        puts [gets $in]
        break
    }
}