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 characters problem 2

Status
Not open for further replies.

pixelz

Programmer
May 8, 2006
32
GB
Hi there,

I've written a small app to get a news headline and story URL out of my MSSQL database and convert it into XML and into an RSS feed. Problem is, of course, that RSS doesn't like '?' or '&' of which my URLs have plenty. If it's an internal url, then no problem, but the minute I use something like: "it doesn't like it!

Now I've written a little function to help me to replace those characters using the replace() function in JScript. This however, just hangs the page until I get a script timout error! Hmmmm.... I've isolated and isolated and it really seems to be the replace function that is at issue. Here's my code:

//I define a new object to hold my conversion values:
function charObject (oldChar, newChar) {
this.oldChar = oldChar;
this.newChar = newChar;
}

//Here is the array of those objects - what to change and what to change to:
var charArray = new Array;
charArray[charArray.length] = new charObject('?','?');
charArray[charArray.length] = new charObject('&','&');

//And this is the replace function:
function replaceChar(thisString) {
//set some variables to ensure correct datatyping
var strReplaceAll = new String(thisString);
var arrLength = charArray.length;

//Now loop through the object array
for (i=0; i<arrLength; i++) {

//check for match
var indexOfMatch = strReplaceAll.indexOf(charArray.oldChar);

//if match, loop through the string while that match exists replacing as we go - the problem seems to be with this loop! even if I just put a Response.Write in there, it still hangs.
while (indexOfMatch != -1) {
//replace first char instance
strReplaceAll = strReplaceAll.replace(charArray.oldChar, charArray.newChar);
//find occurance of next char instance, if it exists
indexOfMatch = strReplaceAll.indexOf(charArray.oldChar);
}
}
//return completed string
return strReplaceAll;
}

For your info, I call this function by doing this:

var urlString = new String(objRec('includeURL'));
var newUrlString = replaceChar(urlString);

where includeURL comes out of my database record (looks like URL above)

Anybody have any idea why this script times out? and do you have any suggestions for how I can work around it?

Thanks SO much!

Pix
 
Hi

Because
[ul]
[li]the new character is the same as the old[/li]
[li]you always search for the old character in the whole string[/li]
[/ul]
So in the second loop the [tt]replace()[/tt] will re-replace the character inserted by the [tt]replace()[/tt] of the first loop, and so on...

Feherke.
 
Hi

By the way, you do not need the loop there :
Code:
[b]function[/b] replaceChar(thisString)
{
  [b]var[/b] strReplaceAll = thisString;
  [b]var[/b] arrLength = charArray.length;

  [b]for[/b] (i=0; i<arrLength; i++)
    strReplaceAll.replace([red]new RegExp([/red]charArray[i].oldChar[red],[i]'g'[/i])[/red], charArray[i].newChar);

  [b]return[/b] strReplaceAll;
}

Feherke.
 
Hey guys!

Wow - thanks for the responses! You guys kick SitePoint's ass!

ok, couple of points - have just noticed that fact that Ferherke pointed out - however, it's supposed to have the unicode value in the 1st argument, so they are subtly different. What I'm wanting to do is replace the ? of the & with the relevant unicode vaules - heh - if I write it out here, it'll probably convert it again! :)

/////////////////////

Code:
strReplaceAll.replace(new RegExp(charArray[i].oldChar,'g'), charArray[i].newChar);

That looks very interesting - can you give me a run down on the theory of it? Am quite new to RegExps so am always looking for places to appy it!

//////////////////////////////

thanks for that monksnake! can you elaborate a little on where I'd use that in my script?

////////////////////////////////

Thanks for all the relpies guys! Most help on this issue I've had in a long time! Brilliant!

Cheers

Pix

 
Right here:

Code:
For your info, I call this function by doing this:

var urlString = [!]escape([/!]String(objRec('includeURL'))[!])[/!];



[monkey][snake] <.
 
Hi

Ok, I give up with the Unicode and will suppose there are strings. I hope this way will be cleaner :
Code:
[gray]// supposing :[/gray]
[gray]// charArray[i].oldChar='[red]foo[/red]'[/gray]
[gray]// charArray[i].newChar='[blue]bar[/blue]'[/gray]

new RegExp([red]charArray[i].oldChar[/red],'[green]g[/green]')
[gray]is the same as[/gray]
/[red]foo[/red]/[green]g[/green]

[gray]so[/gray]

strReplaceAll.replace(new RegExp([red]charArray[i].oldChar[/red],'[green]g[/green]'), [blue]charArray[i].newChar[/blue]);
[gray]is the same as[/gray]
strReplaceAll.replace(/[red]foo[/red]/[green]g[/green],'[blue]bar[/blue]');
                       [red]\_/[/red] [green]|[/green]  [blue]\_/[/blue]
        [red]replace this ---'[/red]  [green]|[/green]   [blue]`--- with this[/blue]
                           [green]|[/green]
                       [green][b][u]g[/u][/b]lobally, in other words all[/green]

Feherke.
 
Beautiful!

Thanks for all the help guys!!

Am gonna apply it now, so will keep you posted.

Cheers,

Pix
 
Hey guys,

OK - have been working on this most of the day but still not having much luck.

Monksnake:
That was a really good idea - just wish it worked coz it would have been really quick and easy. Unfortunately the escape() command turns URLs into something like: http%3A//and the RSS page doesn't recognise it as a URL! Arse!!

:(

Ferherke:
Your method has given me a great amount of hope, but also still having trouble with that too.

If I just use the values for charArray like this:
Code:
var charArray = new Array;
charArray[charArray.length] = new charObject('?','&#63;');
charArray[charArray.length] = new charObject('&','&amp;');

this line
Code:
var re = new RegExp(charArray[i].oldChar,"g");
returns a 'Unexpected quantifier' error. After some hectic Googlisation, I discovered that this is probably because '?' and '&' are special characters in a reg exp.

Hence I've tried various methods to try and escape those characters - things like /\?/ or /\? or \\? or just \? - in the charObject definition. Unfortunately, even though it doesn't make the page fail, no patterns are matched in the strings and the line
Code:
strReplaceAll.replace(re, charArray[i].newChar);
doesn't do any replacing (broke this out into two statements from your original one line above for debugging purposes)

It's becoming clear to me that re (see above) should be a pattern to match to rather than just a string, but I can't seem to get my hand on that pattern.

Any idea how I can work around this problem?

Thanks for all your help so far guys!!

Cheers

Pix
 
Monksnake:
That was a really good idea - just wish it worked coz it would have been really quick and easy. Unfortunately the escape() command turns URLs into something like: http%3A//and the RSS page doesn't recognise it as a URL! Arse!!

When you pull the data back out into you RSS page, you have to then unescape it.

unescape has the same syntax as escape.

[monkey][snake] <.
 
Hi

Let us cut it abit, because I find your code hard to debug. This works for me in FireFox, Opera, Safari and Explorer :
Code:
[b]var[/b] pair=[b]new[/b] Array();
pair[[i]'\\?'[/i]]=[i]'!'[/i];
pair[[i]'&'[/i]]=[i]'%'[/i];
pair[[i]'oldChar'[/i]]=[i]'newChar'[/i];

[b]function[/b] replaceAll(where,what)
{
  [b]var[/b] str=where;
  [b]for[/b] (old [b]in[/b] pair) str=str.replace([b]new[/b] RegExp(old,[i]'g'[/i]),pair[old]);
  [b]return[/b] str;
}

alert(replaceAll([i]'he??o & we?come & enjoy the oldChar'[/i],pair));
[gray]// displays : he!!o % we!come % enjoy the newChar[/gray]

Feherke.
 
Thanks Feherke,

tried this:
Code:
charArray[charArray.length] = new charObject('\\?','&#63;');

but with the same result unfortunately. hmmmmmmm....
the ampersand replace doesn't happen either...

any other ideas?

Thanks!!

Pix
 
Thanks F - will have a look at that!

Cheers!
 
Alright, I looked in detail at this, here's what I came up with. After you posted the textfile, I finally understood your scenario.

Do this, encapsulate the data in your <link> and <guid> tags with CDATA, so the XML parser won't try to parse that information, leaving it as is.

It'll look like this:

Code:
<item>
   <title><%= objRec('headline') %></title>
   <description><%= objRec('headline') %></description>
   <link>[!]<![CDATA[[/!] [URL unfurl="true"]http://www.ncri.org.uk/default.asp&#63;sectionID=News&amp;articleID=<%=objRec("ID")%>[/URL][!]]]>[/!]</link>
   <guid>[!]<![CDATA[[/!] [URL unfurl="true"]http://www.ncri.org.uk/default.asp&#63;sectionID=News&amp;articleID=<%=objRec("ID")%>[/URL][!]]]>[/!]</guid>
</item>



[monkey][snake] <.
 
OK!

Beauty! Finally that worked! *sheesh* You've really saved me from pulling (more) hair out in fustration.

I wish I could understand the difference between your code and mine though, F. Looking at it, it seems functionally the same but I can't isolate where I went wrong. :(

Nevermind - it's working beautifully now anyway. Thanks for all your help guys!!

Pix
 
Ah thanks monksnake! didn't see your post when I wrote the above one.

Sounds good - will give that a go too. would be a hell of a lot better if I had lots of links and that replace function slowed everything down.

Cheers guys!!

Pix
 
Excellent! That worked too!

hahaaaaa!! now have 2 strings in my bow!! NOICE!!

Jeez - thanks a lot guys! You really saved my life here! Death by fustration is NOT a pretty sight!

:)

Pix
 
Hi

Pix, please press on of the links in monksnake's post, which says :

[navy]* Thank monksnake
for this valuable post!
[/navy]

Then confirm the question in the window which will pop up.

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top