如何获取tcl中匹配字符串下的文本

时间:2013-03-05 13:17:33

标签: regex tcl

我在tcl中有一个字符串值

set out " ABC CDE EFG 
          123     456"

我想获取文字“EFG”下方的文字。 现在它是“456”,但它可以是任何东西,所以我需要一种方法,我可以grep“EFG”并获得它下面的文本。

3 个答案:

答案 0 :(得分:2)

这个答案从Johannes Kuhn的回答中得到了一些启发,但我使用regexp从“键”行获得单词索引。

# this is as close as I can get to a here-doc in Tcl
set out [string trim {
ABC DEF GHI
123     456
}]

# map the words in the first line to the values in the 2nd line
lassign [split $out \n] keys values
foreach range [regexp -all -inline -indices {\S+} $keys] {
    set data([string range $keys {*}$range]) [string range $values {*}$range]
}
parray data

输出

data(ABC) = 123
data(DEF) =    
data(GHI) = 456

答案 1 :(得分:1)

我建议用

将字符串拆分为键和值
lassign [split $out \n] keys values

然后在键中查找字符串位置并在值

中获得相同的范围
set start [string first "EFG" $keys]
set value [string range $values $start [expr {${start}+[string length "EFG"]-1}]]

将它包裹在一个proc中,我们得到

proc getValue {input lookFor} {
    lassign [split $input \n] keys values
    set start [string first $lookfor $keys]
    set value [string range $values $start \
        [expr {${start}+[string length $lookfor]-1}]]
}

像这样调用它:

getValue $out "EFG"

编辑:第二行是如何对齐的?使用制表符(\t),空格?

答案 2 :(得分:0)

在这种情况下,您实际拥有的是两行,其中3个字母数字字符组由空格分隔,前面有大量前导空格,第二行("\x20ABC\x20CDE\x20EFG\n[string repeat \x20 10]123[string repeat \x20 5]456"将重现您发布的内容)。在您的示例中,[string range end-2 end]会为您提供所需内容。我建议逐行读取文件,每次看到EFG时,在下一行提取你需要的部分(可能使用字符串范围)并发出它。

例如(未经测试):

set state 0
set f [open $inputfile r]
while {[gets $f line] != -1} {
    if {$state} {
        puts [string range $line end-2 end]
        set state 0
    } else {
        if {[string match "*EFG" $line]} { set state 1 }
    }
}
close $f