我在tcl中有一个字符串值
set out " ABC CDE EFG
123 456"
我想获取文字“EFG”下方的文字。 现在它是“456”,但它可以是任何东西,所以我需要一种方法,我可以grep“EFG”并获得它下面的文本。
答案 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