This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

[SOLVED] replace a certain value

Help for those learning Tcl or writing their own scripts.
Post Reply
r
raider2k
Op
Posts: 140
Joined: Tue Jan 01, 2008 10:42 am

[SOLVED] replace a certain value

Post by raider2k »

im looking for a way to replace a certain value with almost the same value, the difference is that the new value is the same text, only different colours.

eg:

list that contains A B C D E

want to replace lindex $list 2 (so letter C) with the same value (letter C ^^) again but also coloured. somehow i ran out of ideas, please help
Last edited by raider2k on Wed Jul 08, 2009 9:09 am, edited 1 time in total.
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

You would need to clarify exactly what you are trying to replace.

For example, always a certain character. For which you could use regsub

Code: Select all

set rlist {A B C D E}
set rchar C
set result [regsub -all -- [subst {$rchar}] $rlist \00304&\003]
Or, always a certain list index, for which you could use lreplace

Code: Select all

set rlist {A B C D E}
set rposn 2
set result [lreplace $rlist $rposn $rposn \00304[lindex $rlist $rposn]\003]
Both the above yield a value for result which replaces the character C (list index 2) with the same character in red foreground colour.

There are other options such as using string map for a string value

Code: Select all

set rstring "A B C D E"
set result [string map {C \00304C\003} $rstring]
I must have had nothing to do
r
raider2k
Op
Posts: 140
Joined: Tue Jan 01, 2008 10:42 am

Post by raider2k »

oh, very nice :)

what does \00304&\003 exactly do in:

Code: Select all

set result [regsub -all -- [subst {$rchar}] $rlist \00304&\003]
i know what those colourcodes do, but &?

even though you use a fixed given char here:

Code: Select all

set rlist {A B C D E}
set rchar C
set result [regsub -all -- [subst {$rchar}] $rlist \00304&\003]
i think its also possible to do it like this:
(or at least i hope so, please correct if im wrong)

Code: Select all

set rlist {whatever is in here}
set rchar [lindex $rlist 2]
set result [regsub -all -- [subst {$rchar}] $rlist \00304&\003]
since the list an its values are different most of the time.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

With regsub, "&" within the subSpec parameter means "insert whatever matched exp here".

You may certainly create the regular expression to be used on the fly, although you'll need to care for a proper expression (having a value of .* would most certainly not generate the result you intended), as regsub uses regular expression pattern-matching rather than literal string-matching.

I'm not sure why there's a subst in there for starters though, especially since the evaluation is blocked using {}. I'd rather suggest building a proper regular expression by hand.

One word of caution, whenever you use regsub on a list, the output technically is no longer a list, but a string. With some friendly modifications, the list structure would probably still be valid, but it cannot be guaranteed. The same goes for string map.

Saying which approach you should use is rather hard with the limited description given. However, if you need pattern-based substitutions, regsub is your friend. If you're rather looking for a single list item, or mere literal strings to be replaced, you'd be better off using other approaches.
NML_375
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

The subst command was there to force substitution of the variable name by it's value. Sticking to the convention of surrounding the regsub pattern with braces would otherwise have prevented substitution.

More generally, I would use

Code: Select all

[regsub -all -- [subst -nobackslashes -nocommands {$rchar}] $rlist \00304&\003]
Because regexp/regsub patterns frequently contain characters which I definitely would not want to subsitute, though not in this case.
I must have had nothing to do
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

arfer,
The practice of enclosing patterns with {} is mainly due to the fact that regular pattern makes use of [] and \. If you store your expression in a variable, there would be no use for {}. Also, with proper escaping, you could simply use "" as well. This is nothing unique for regsub, but in any case where you'd have to have one []\ or similar within your string.

Below you'll find a few examples each doing the very same substitutions, having the exact same expressions, strings and subspecs...

Code: Select all

set somestring "Hello world!"
#set somestring {Hello world!}

#Works well, might look a little messy...
regsub -- "\[a-zA-Z0-9\]+" $somestring "\00304\\0\003"

#Works well, considered the preferred way when including the exp and subSpec literally into the commandline
regsub -- {[a-zA-Z0-9]} $somestring "\00304&\003"

#Works well, separates the exp and subSpec from the command
set exp {[a-zA-Z0-9]}
#set exp "\[a-zA-Z0-9\]"

set subSpec "\00304&\003"
regsub -- $exp $somestring $subSpec

#Overworked, and looks messy... still works though...
regsub -- [subst {$exp}] [subst {$somestring}] [subst {$subSpec}]
NML_375
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Thanks nml375, though I know.

After a few mishaps, I sort of stick to the convention of braces (if I can).
I must have had nothing to do
r
raider2k
Op
Posts: 140
Joined: Tue Jan 01, 2008 10:42 am

Post by raider2k »

guys, thanks very much to both of you since you helped me out of what i got stuck with and also i now experienced some answers regarding regsub i was looking for before

thanks very much :)
Post Reply