Как использовать expr внутри regsub в TCL?

Предположим, set s1 "some4number"

Я хочу изменить его на some5number.

Я надеялся, что это сработает:

regsub {(\d)(\S+)} $s1 "[expr \\1 + 1]\\2"

Но выдает ошибку. Каким был бы идеальный способ сделать это в TCL?


person Sidharth C. Nadhan    schedule 06.07.2017    source источник
comment
Я сейчас на своем мобильном телефоне, поэтому я не могу правильно ответить, но это раздражающе сложно, таково резюме. Если только у вас не Tcl 8.7, где я добавил параметр -command к regsub, но он по-прежнему находится в статусе только для проверки исходного кода.   -  person Donal Fellows    schedule 06.07.2017


Ответы (1)


В Tcler's Wiki есть много полезных вещей. Одним из них является это:

# There are times when looking at this I think that the abyss is staring back
proc regsub-eval {re string cmd} {
    subst [regsub $re [string map {[ \\[ ] \\] $ \\$ \\ \\\\} $string] \[$cmd\]]
}

С этим мы можем сделать это:

set s1 "some4number"
# Note: RE changed to use forward lookahead
set s2 [regsub-eval {\d(?=\S+)} $s1 {expr & + 1}]
# ==> some5number

Но это станет менее ужасным в будущем с 8.7 (в разработке). Вот что бы вы сделали с помощником apply-term:

set s2 [regsub -command {(\d)(\S+)} $s1 {apply {{- 1 2} {
    return "[expr {$1 + 1}]$2"
}}}]

Вместо этого с помощью вспомогательной процедуры:

proc incrValueHelper {- 1 2} {
    return "[expr {$1 + 1}]$2"
}
set s2 [regsub -command {(\d)(\S+)} $s1 incrValueHelper]
person Donal Fellows    schedule 06.07.2017