は、-all
スイッチと一致変数間の相互作用は、マッチングの最後の反復でキャプチャ値は変数を埋めるために使用されることです。つまり、1つのキャプチャグループを持ち、8回繰り返して8つの変数を入力することはできません。
最後のフィールドの後にコンマが必要なため、正規表現が一致しません。
この特定の例では、あなたはこれがコンマない文字のすべてのグループと一致することを意味し
% regexp -all -inline {[^,]+} $line
{2017/08/21 16:06:20.0} { REALTIME} { late by 0.3} { EOS450D} { 1/640} { F/8.0} { ISO 100} { Partial 450D 0.0%}
呼び出しを使用することができます(コンマは特別なものではありませんのでご注意:あなたがする必要はありませんそれをエスケープして)リストとして返します。
あなたが述べたように、これは(約5倍の速さでもある)
% split $line ,
を使用するのと同じです。あなたがやりたいことの検証の形式は不明ですが、あなたは簡単に見つかったフィールドの数を検証することができます:
あなたは、いくつかの検証をやってみたかったのでsplit
を使いたくなかった
% set fields [split $line ,]
% if {[llength $fields] ne 8} {puts stderr "wrong number of fields"}
をあなたは、変数内のフィールドを保存し、それらを抽出しながら、同時にそれらすべてを検証しようとするよりも権利を取得するために多くの方が簡単である、それらを個別に検証することができます。
lassign $fields date tm off cam exp fnum iso com
if {![regexp {ISO\s+\d+} $iso]} {puts stderr "in search of valid ISO"}
最善の方法は、データを分割することはまだありますを使用している文字列パッケージ。この単純化されたCSVを今すぐ使用したいと思っても、早急に、コンマで区切られたフィールドを許可したいと思うかもしれません。
package require csv
set fields [::csv::split $line]
ドキュメント: csv (package)、 if、 lassign、 llength、 package、 puts、 regexp、 set、 split、 Syntax of Tcl regular expressions
ETA:先頭/末尾の空白を取り除くこと。 CSVデータは、通常、セパレータ文字で区切られた厳密に重要なテキストのフィールドに配置されるため、これは少し珍しいことです。トリムするものがある場合は、通常、データを保存するときに実行されます。
lmap field [regexp -all -inline {[^,]+} $line] {string trim $field}
もう一つの方法は、最初のコンマの周りの空白を取り除くことであり、その後、スプリット:
split [regsub -all {\s*,\s*} $line ,] ,
良い方法はlmap
/string trim
フィルターを通してマッチしたグループを置くことです正規表現で分割するsplit
のTcllibバリアントを使用することができます。
package require textutil
::textutil::splitx $line {\s*,\s*}
[^\s,][^,]*[^\s,]
の以前の正規表現をスワップアウトすることもできます(2文字未満のフィールドには一致しません)。これは、あまりにも複雑になりすぎて、有用ではないように見える正規表現です。
私は今テストすることはできませんが、コードを見ると、最後のフィールドの後にカンマがないため(適切であるため)、チョークする可能性が高いと思われます。私は、Tcllibのcsvパッケージを使ってcsvを単純化することを強くお勧めします。 –