user1795370
user1795370

Reputation: 342

tcl regsub will not work

I'm trying to write an extremely simple piece of code and tcl is not cooperating. I can only imagine there is a very simple error I am missing in my code but I have absolutely no idea what it could be please help I'm so frustrated!!

My code is the following ...

proc substitution {stringToSub} {
   set afterSub $stringToSub
   regsub {^.*?/projects} "$stringToSub" "//Path/projects" afterSub
   regsub {C:/projects} "$stringToSub" "//Path/projects" afterSub
   return $afterSub
}

puts "[substitution /projects] "
puts "[substitution C:/projects] "

The substitution works fine for the second expression but not the first one. Why is that?? I have also tried using

regsub {^/projects} "$stringToSub" "//Path/projects" afterSub

and

regsub {/projects} "$stringToSub" "//Path/projects" afterSub

but neither are working. What is going on??

Upvotes: 1

Views: 715

Answers (3)

Donal Fellows
Donal Fellows

Reputation: 137567

The issue is that your second use of the regsub operation is overwriting the substituted value from the first regsub use.

We could simplify the code to just this:

proc substitution {stringToSub} {
    return [regsub {^.*?/projects} $stringToSub "//Path/projects"]
}

Upvotes: 1

potrzebie
potrzebie

Reputation: 1798

The first two lines in your procedure will effectively do nothing, since regsub always overwrites the destination variable (afterSub) even when there's 0 matches/substitutions made. From the regsub manual:

This command matches the regular expression exp against string, and either copies string to the variable whose name is given by varName or returns string if varName is not present. (Regular expression matching is described in the re_syntax reference page.) If there is a match, then while copying string to varName (or to the result of this command if varName is not present) the portion of string that matched exp is replaced with subSpec.

There's no need to match C:/projects specifically, because ^.*?/projects will match that text?

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

Since yours two regsub calls don't change the input string (i.e.: $stringToSub) but put the result in the string $afterSub which is returned by the function. You will always obtain the result of the last regsub call and the result of the first regsub call in $aftersub is always overwritten.

Note that the first pattern is more general and include all the strings matched by the second (assuming that $stringToSub is always a path). If you hope to obtain "//Path/projects" for your sample strings, you can simply remove the second regsub call:

proc substitution {stringToSub} {
    set afterSub $stringToSub
    regsub {^.*?/projects} "$stringToSub" "//Path/projects" afterSub
    return $afterSub
}

Upvotes: 1

Related Questions