0

Suppose, set s1 "some4number"

I want to change it to some5number.

I was hoping that this would work :

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

But it errors out. What would be the ideal way to do this in TCL ?

Sidharth C. Nadhan
  • 2,191
  • 2
  • 17
  • 16
  • I'm on my mobile right now so I can't answer properly, but "it is annoyingly complicated" is the summary. Unless you have Tcl 8.7 where I added a `-command` option to `regsub`, but that is still in check-out-of-source-control-only status. – Donal Fellows Jul 06 '17 at 09:52

1 Answers1

2

The Tcler's Wiki has many neat things. One of them is this:

# 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\]]
}

With that, we can do this:

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

But this will become less awful in the future with 8.7 (in development). Here's what you'd do with an apply-term helper:

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

With a helper procedure instead:

proc incrValueHelper {- 1 2} {
    return "[expr {$1 + 1}]$2"
}
set s2 [regsub -command {(\d)(\S+)} $s1 incrValueHelper]
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215