Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

replacing strings with & (ampersand) in them using regsub

Status
Not open for further replies.

cubicle4

Programmer
Jun 18, 2001
18
US
Hi all,

BTW, in my examples below where you see &quot;<&quot; and &quot;>&quot; replace them with the HTML entity when running the scripts, the browser has converted them to the actual character.

Seems like all my issues revovle around mappings and string replacement. aarrghh! Anyhow, I have a string that has an ampersand in it. I tried using regsub and of course if substituted the string but also substitued the ampersand in the string with the original string value, see example:

set termsURL /files/22994_HL&P_Terms_of_Service.pdf

set contentDetails_5 &quot;account(s) or other transactions with Reliant Energy. I
have read and understand the <inserttermshere>. I am at least eighteen yea
rs of age and legally authorized to change REP's for the address(es) listed abov
e.</font></p>&quot;

regsub -all -- {<inserttermshere>} $contentDetails_5 $termsURL contentDetails_5


See the problem? Well, to work around this I wrote this little script to do the replacement instead, just wondering if their was a better way?

set termsURL /files/22994_HL&P_Terms_of_Service.pdf

set contentDetails_5 &quot;account(s) or other transactions with Reliant Energy. I have read and understand the <inserttermshere>. I am at least eighteen years of age and legally authorized to change REP's for the address(es) listed above.</font></p>&quot;

set search_index {0}
set open_terms [string first &quot;<insert&quot; [string tolower [string range $contentDetails_5 $search_index end]]]
set close_terms [string first &quot;here>&quot; [string tolower [string range $contentDetails_5 $search_index end]]]
set current_begin_index [expr $open_terms -1]
set current_close_index [expr $close_terms + 1]


set stringToReplace {}
set stringToReplace &quot;[string range $contentDetails_5 $open_terms [expr $close_terms + 7]]&quot;

set rebuilt_string [string range $contentDetails_5 0 $current_begin_index]
append rebuilt_string $termsURL

append rebuilt_string [string range $contentDetails_5 [expr $current_close_index + 7] end]
set input_string $rebuilt_string

TIA,

Harold
 
Standard regsub behavior. Paraphrasing the regsub reference page:

&quot;If the {replacement string} contains a “&” or “\0”, then it is replaced in the substitution with the portion of string that matched {expression}.

A simplified example:

[tt]% set replacement &quot;Ken & Dean&quot;
Ken & Dean
% set text &quot;Hello, <name>!&quot;
Hello, <name>!
% regsub -all -- &quot;<name>&quot; $text $replacement result
1
% puts $result
Hello, Ken <name> Dean![/tt]

To prevent the substitution from occurring, you must have a literal &quot;\&quot; before the &quot;&&quot; in your replacement string. Of course, since &quot;\&quot; is already a special character to the Tcl interpreter, you might need to use &quot;\\&quot;, as shown here:

[tt]% set replacement &quot;Ken \\& Dean&quot;
Ken \& Dean
% regsub -all -- &quot;<name>&quot; $text $replacement result
1
% puts $result
Hello, Ken & Dean![/tt]

Alternately, we could have used {} to quote our replacement string, in which case we wouldn't have to double up the &quot;\&quot;:

[tt]% set replacement {Ken \& Dean}
Ken \& Dean
% regsub -all -- &quot;<name>&quot; $text $replacement result
1
% puts $result
Hello, Ken & Dean![/tt] - Ken Jones, President
Avia Training and Consulting
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Ken,

Usually, I am enlightened by your responses. However, this time I was aware of the regsub behavior with regards to ampersands and likewise I agree with you. Also, and I should have included this relevant information in the initial post, the string(file path) that I am wanting to regsub is user generated and submitted via a content management system. Unfortunately, we cannot impose rules on our users or expect them to enter a file path with escaped characters. Short of the long is that I have to take into account the fact that a user could have a file path with an ampersand in it. Having this knowledge, does this seem like the right thing to do, or rather the right way to handle this exception.

TIA
Harold
 
Oh yeah, and one more thing. Like Bong said, &quot;you're the man&quot;.
 
Oops. Sorry, I managed to breeze right past the part of your original post where you acknowledged the behavior of &quot;&&quot; in a regsub replacement.

Well, since you don't have direct control over what the user inputs, how about massaging their input before doing your regsub? If you're using Tcl 8.1.1 or later, you can use string map, which makes it really simple:

[tt]% set replacement &quot;Ken & Dean&quot;
Ken & Dean
% [ignore]set replacement [string map {& \\&} $replacement][/ignore]
Ken \& Dean
% regsub -all -- &quot;<name>&quot; $text $replacement result
1
% puts $result
Hello, Ken & Dean![/tt]

If you're using an earlier version of Tcl, you can accomplish the same thing with regsub, but it isn't as pretty:

[tt]% regsub -all -- {&} $replacement {\\\&} replacement
1
% puts $replacement
Ken \& Dean[/tt]

Actually, now that I think of it, if you're using Tcl 8.1.1 or later, you could skip all of the regsub stuff altogether, and let string map take care of it all. Then you completely sidestep the &quot;&&quot; issue:

[tt]% set replacement &quot;Ken & Dean&quot;
Ken & Dean
% set text &quot;Hello, <name>!&quot;
Hello, <name>!
% [/ignore]set text [string map [list <name> $replacement] $text][/ignore]
Hello, Ken & Dean![/tt] - Ken Jones, President
Avia Training and Consulting
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top