TCL 正则表达式不返回预期的匹配项



我正在从文件名中提取电压的数值数据。该名称包含三个此类数据,但正则表达式仅返回 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 演示。

只是为了澄清这里的"不消耗"是什么意思:(?=_),一种非消费模式,不会将_放入正则表达式匹配值中,并且在执行前瞻模式时,正则表达式索引保持在_之前。因此,下一场比赛可以在此_之前开始。

最新更新