Вы можете использовать свой шаблон, но перебираете строку для поиска всех вхождений первого символа, _
(обратите внимание, что это можно сделать с помощью регулярного выражения, используя опцию -indices
, если первый символ не является "жестко закодированным", но здесь вы можете использовать просто string first
) и проверить соответствие регулярному выражению в каждом из этих мест. Если совпадение найдено, lappend
совпадение и первый захват в списке.
См. Демонстрационный код Tcl :
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
set RE {_(\dp\d{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's подход , но вам придется реконструировать выходные данные, изучив все элементы в результирующем списке и добавив _
к тем элементам, которые начинаются с _
:
set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
set RE {_(\dp\d{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 онлайн .
Просто уточнить, что здесь означает «не потребляет»: (?=_)
, некоммутирующий шаблон, не помещает _
в значение соответствия регулярному выражению, и индекс регулярного выражения остается прямо перед _
, когда образец ожидания выполнен. Таким образом, следующий матч может начаться прямо перед этим _
.