ファイルから解析する一連のフィールドがあり、foreachループ内で1行ずつ解析しています。1行スキップして次の行に移動する方法を知りたいです。
例:「ABC」という文字列に遭遇した場合、次の行の数字を取得する必要があります。
一部の文字「ABC」 123
問題は、実際にはファイルに多数の数字が含まれていることですが、数字、具体的には文字列「ABC」の後の改行の後の数字を取得する必要があります。
これどうやってするの ?
ファイルから解析する一連のフィールドがあり、foreachループ内で1行ずつ解析しています。1行スキップして次の行に移動する方法を知りたいです。
例:「ABC」という文字列に遭遇した場合、次の行の数字を取得する必要があります。
一部の文字「ABC」 123
問題は、実際にはファイルに多数の数字が含まれていることですが、数字、具体的には文字列「ABC」の後の改行の後の数字を取得する必要があります。
これどうやってするの ?
この簡単な解決策を試すことができます
set trigger 0
set fh [open "your_file" "r"]
while {[gets $fh line] != -1} {
if {[regexp -- {"ABC"} $line]} {
incr trigger
continue
}
if {$trigger > 0} {
puts $line ; # or do something else
incr trigger -1
}
}
close $fh
トリガーケースを見つけたときに余分なwhile
行を簡単に読み取ることができるため、ループを使用して一度に1行ずつ読み取る方が少し簡単です(行が含まれていない場合)。"ABC"
set fd [open $theFilename]
while {[gets $fd line] >= 0} {
if {
[string match *"ABC"* $line]
&& [gets $fd line] >= 0
&& [regexp {\d+} $line -> num]
} then { # I like to use 'then' after a multi-line conditional; it's optional
puts "Found number $num after \"ABC\""
}
}
close $fd
これが厄介な理由はforeach
、ループを通過するたびに常に同じ数の要素を処理するためです。
上記でほのめかされた行の不足の問題が発生する可能性のあるデータを扱っている場合は、foreach
不思議なことに、実際には次のようにしたほうがよいでしょう。
set fd [open $theFilename]
set lines [split [read $fd] \n]
close $fd
foreach line $lines {
incr idx; # Always the index of the *next* line
if {
[string match *"ABC"* $line]
&& [regexp {\d+} [lindex $lines $idx] -> num]
} then {
puts "Found number $num after \"ABC\""
}
}
これが機能するlindex
のは、最後を超えて何かを行うと、空の文字列が生成されるためです(これはその単純な正規表現とは一致しません)。