我正在从文件名中提取电压的数值数据。该名称包含三个此类数据,但正则表达式仅返回 2
。set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
regexp -all -inline {_(dpd{3})v_} $data
返回:
_0p500v_ 0p500 _0p550v_ 0p550
我期待:
_0p500v_ 0p500 _0p530v_ 0p530 _0p550v_ 0p550
不知道缺少什么。
感谢您的帮助。
使用积极的展望:
_(dpd{3})v(?=_)
这样,以下下划线不会被使用,并且已准备好与下一次迭代匹配。
要在匹配部分追加_
:
set output [regexp -all -inline {_(dpd{3})v(?=_)} $data]
set index 0
foreach item $output {
puts [expr {$index % 2 == 0 ? "$item_": $item}]
incr index
}
现场演示
您可以使用您的模式,但迭代字符串搜索第一个字符的所有匹配项,_
(请注意,如果第一个字符不是"硬编码"的,则可以使用正则表达式-indices
选项来完成,但在这里您可以使用仅string first
(,并检查每个位置的正则表达式匹配项。如果找到匹配项,则将匹配项和第一个捕获lappend
到列表中。
请参阅 Tcl 代码演示:
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
set RE {_(dpd{3}v)_}
set result []
set idx [string first "_" $data 0]
while {$idx > -1} {
if {[regexp -start $idx $RE $data whole between]==1} {
lappend result $whole $between
}
set idx [string first "_" $data $idx+1]
}
puts $result
输出:
_0p500v_ 0p500v _0p530v_ 0p530v _0p550v_ 0p550v
请注意,您可以使用@revo的方法,但您必须通过检查结果列表中的所有项目并将_
附加到以_
开头的项目中来重建输出:
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
set RE {_(dpd{3}v)(?=_)}
set ms [regexp -all -inline $RE $data]
set result []
foreach m $ms {
if {[string index $m 0] == "_"} {
lappend result "${m}_"
} else {
lappend result $m
}
}
puts $result
在线查看另一个 Tcl 演示。
只是为了澄清这里的"不消耗"是什么意思:(?=_)
,一种非消费模式,不会将_
放入正则表达式匹配值中,并且在执行前瞻模式时,正则表达式索引保持在_
之前。因此,下一场比赛可以在此_
之前开始。