From: Koszalek Opalek on
I'd like to increase all three digit numbers in a relatively long
string (1k-5k) by one.
The common perl idiom would be:
s/(\d{3})/$1 + 1/ge
The /e flag specifies that the replacement should be evaluated as an
expression
rather than the string. This gives me exactly what I want (I have
ignored
complications that might arise from leading zeros -- those are easy to
fix).

What would be the most elegant way to achieve the same effect in Tcl
(where the
replacement cannot be evaluated as an expression)?

K.
From: Alexandre Ferrieux on
On 12 juin, 18:16, Koszalek Opalek <koszalekopa...(a)interia.pl> wrote:
> I'd like to increase all three digit numbers in a relatively long
> string (1k-5k) by one.
> The common perl idiom would be:
>    s/(\d{3})/$1 + 1/ge
> The /e flag specifies that the replacement should be evaluated as an
> expression
> rather than the string. This gives me exactly what I want  (I have
> ignored
> complications that might arise from leading zeros -- those are easy to
> fix).
>
> What would be the most elegant way to achieve the same effect in Tcl
> (where the
> replacement cannot be evaluated as an expression)?
>
> K.

While Tcl doesn't have the equivalent of that right-hand-side-eval
idiom, you can emulate it in three steps:

proc incrdig s {

# protect existing \ and [] by a \
regsub -all {[][\\]} $s {\\&} s

# do your substitutions producing []-enclosed expressions
regsub -all {\d{3}} $s {[expr {&+1}]} s

# do command substitutions. only yours are active at this stage.
return [subst -novariables $s]
}

Note that the \d{3} regexp may not be what you want if 4+ -digit
strings occur, but that is also the case of your perl code so I
emulated your bug ;-)

HTH,

-Alex
From: Harald Oehlmann on
On 12 Jun., 18:26, Alexandre Ferrieux <alexandre.ferri...(a)gmail.com>
wrote:
> While Tcl doesn't have the equivalent of that right-hand-side-eval
> idiom, you can emulate it in three steps:

Very clear and complete answer, thank you Alex !
From: Andreas Leitgeb on
Alexandre Ferrieux <alexandre.ferrieux(a)gmail.com> wrote:
> On 12 juin, 18:16, Koszalek Opalek <koszalekopa...(a)interia.pl> wrote:
>> I'd like to increase all three digit numbers in a relatively long
>> string (1k-5k) by one.
>> The common perl idiom would be:
>>    s/(\d{3})/$1 + 1/ge
> While Tcl doesn't have the equivalent of that right-hand-side-eval
> idiom, you can emulate it in three steps:
>
> proc incrdig s {
>
> # protect existing \ and [] by a \
> regsub -all {[][\\]} $s {\\&} s
>
> # do your substitutions producing []-enclosed expressions
> regsub -all {\d{3}} $s {[expr {&+1}]} s
>
> # do command substitutions. only yours are active at this stage.
> return [subst -novariables $s]
> }

As soon as one solution is given by someone, there inevitably starts
a contest of improving it gradually... :-)

I'd define a separate
proc +1 {x} {expr {[scan %d $x]+1}
and change the second step to:
regsub -all {\d{3}} $s {[+1 &]} s

Downside of it is spoiling the global namespace with a temporary
function, upsides are, that the intermediary string $s will not grow
all that much, that it deals with leading zeros, and (just guessing)
that it will still allow the actual expr (in "+1"'s body) to be byte-
compiled.