TCL регулярное выражение не возвращает ожидаемые совпадения - PullRequest
0 голосов
/ 09 мая 2018

Я извлекаю числовые данные напряжений из имени файла. Имя содержит три таких данных, но регулярное выражение возвращает только 2.

set data "blabla_0p500v_0p530v_0p550v_m25c_foo.dat"
regexp -all -inline {_(\dp\d{3})v_} $data

Возвращает:

_0p500v_ 0p500 _0p550v_ 0p550

Я ожидал:

_0p500v_ 0p500 _0p530v_ 0p530 _0p550v_ 0p550

Не уверен, чего не хватает.

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Вы можете использовать свой шаблон, но перебираете строку для поиска всех вхождений первого символа, _ (обратите внимание, что это можно сделать с помощью регулярного выражения, используя опцию -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 онлайн .

Просто уточнить, что здесь означает «не потребляет»: (?=_), некоммутирующий шаблон, не помещает _ в значение соответствия регулярному выражению, и индекс регулярного выражения остается прямо перед _, когда образец ожидания выполнен. Таким образом, следующий матч может начаться прямо перед этим _.

0 голосов
/ 09 мая 2018

Используйте позитивный взгляд:

_(\dp\d{3})v(?=_)

Таким образом, следующее подчеркивание не расходуется и готово к сопоставлению на следующей итерации.

Добавить _ в согласованной части:

set output [regexp -all -inline {_(\dp\d{3})v(?=_)} $data]
set index 0
foreach item $output {
  puts [expr {$index % 2 == 0 ? "$item\_": $item}]
  incr index
}

Живая демоверсия

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...