我有一个带有固定给定数字和字符串的文本行,如下所示:
set line " 0.123 -0.1 +0.31 +1.4 foo bar "
我尝试使用regexp来取出所有数字和'bar'。我不需要字符串'foo'。
这会找到一个数字: (?[ - +](\ d + \ d *))
为了捕捉这组数字,我可以连接模式,但看起来很难看。有没有办法触发数字模式的多个匹配,然后是字符串模式的几个匹配?
像这样:
set line " 0.123 -0.1 +0.31 +1.4 foo bar "
regexp {magic_pattern} $line dummy n0 n1 n2 n3 s0 s1
puts $n0
0.123
puts $n1
-0.1
puts $n2
0.31
puts $n3
1.4
puts $s0
foo
puts $s1
bar
在适用时,数字将是所有具有零的前导小数点的浮点数,并且没有指数表示法。所有都是基数10,没有十六进制或二进制。
干杯, 格特
答案 0 :(得分:2)
嗯,除了连接正则表达式之外别无他法......
set line " 0.123 -0.1 +0.31 +1.4 foo bar "
regexp {([-+]?\d+\.\d*) ([-+]?\d+\.\d*) ([-+]?\d+\.\d*) ([-+]?\d+\.\d*) (\S+) (\S+)} $line dummy n0 n1 n2 n3 s0 s1
\S+
将匹配任何非空格字符。假设foo
和bar
都不能包含空格,我已经使用过它。否则可能需要更好的模式。
或者你可以用不同的方式构建它:
set num {([-+]?\d+\.\d*)}
set name {(\S+)}
regexp "$num $num $num $num $name $name" $line dummy n0 n1 n2 n3 s0 s1
答案 1 :(得分:0)
split
和lassign
会更容易:
set line " 0.123 -0.1 +0.31 +1.4 foo bar "
set fields [split [string trim $line]]
if {[llength $fields] != 6} continue ;# handle missing fields somehow
lassign $fields n0 n1 n2 n3 s0 s1
puts "$n0:$n1:$n2:$n3:$s0:$s1"
0.123:-0.1:+0.31:+1.4:foo:bar
否则,如果您需要正则表达式:
set fields [regexp -all -inline {[+-]?(?:\d+\.?\d*|\d*\.\d+)|\S+} $line]
if {[llength $fields] != 6} continue ;# handle missing fields somehow
puts $fields
0.123 -0.1 +0.31 +1.4 foo bar