dumpsite.com
October 30, 2014, 08:07:33 am *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Javascript replaceAll function  (Read 35753 times)
Black Bart
Newbie
*
Posts: 5


« on: July 02, 2011, 04:34:46 pm »

I continue to see this foolish technique presented as javascript replaceAll function.

Can anyone see the problem with this?

function replaceAll(str, str1, str2)
{
   var index = str.indexOf( str1 );
 
   while (index != -1)
   {
      str = str.replace(str1, str2);
 
      index = str.indexOf(str1);
   }
 
   return str;
}
Logged
Ron White
Newbie
*
Posts: 1


« Reply #1 on: July 03, 2011, 09:01:22 am »

That replaceAll function will create an endless loop under the following conditions:

var myString = "x";

myString = replaceAll(myString,  "x", "xyz");

Try something like this:

function replaceAll(str, str1, str2)
{
   return str.replace(new RegExp(str1, "g"), str2);
}

It's simple and effective.
Logged
Black Bart
Newbie
*
Posts: 5


« Reply #2 on: July 03, 2011, 12:00:34 pm »

The problem with using a regular expression is that there are too many special characters that need to be escaped.

Consider the following will produce $100.00-
instead of -100.00 which is what you might have expected.

replaceAll("$100.00",  "$", "-");

Also,

replaceAll("$100.00", ".", "")

produces the empty string, rather than $10000

Lastly,

replaceAll("Hello?", "?", "!")

Will give you a javascript error rather than Hello!

I could go on with this.

There has to be a better way.


Logged
qwerty
Newbie
*
Posts: 7


« Reply #3 on: July 13, 2011, 06:33:56 pm »


Here is the latest function posted as code:

Code:
String.prototype.replaceAll = function(str1, str2, ignore)
{
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
}

Here is a modified version that corrects the issues you raise and also supports "ignore case" as an optional boolean.

You just need to escape all the regex special characters.

String.prototype.replaceAll = function(str1, str2, ignore)
{
   return this.replace(new RegExp(str1.replace(/([\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, function(c){return "\\" + c;}), "g"+(ignore?"i":"")), str2);
};

This code adds a replaceAll method to the String object.

You call it like this:

var myString = "Hello???";

myString.replaceAll("?", "!");

And it will return this:

Hello!!!

See if you can break it.
« Last Edit: July 23, 2011, 09:07:53 am by qwerty » Logged
Bailyn
Newbie
*
Posts: 6


« Reply #4 on: July 15, 2011, 09:50:48 am »

Hi qwerty ... that's pretty impressive.  Compact, simple but powerful! ... That's about my contribution to this topic.  I will let you know when I break it.
Logged
qwerty
Newbie
*
Posts: 7


« Reply #5 on: July 15, 2011, 05:21:47 pm »

Thanks Bailyn,

Let me know if you break it, or you have something better, but make sure it can pass these 4 tests:

"x".replaceAll("x", "xyz");
xyz

"x".replaceAll("", "xyz");
xyzxxyz

"aA".replaceAll("a", "b", true);
bb

"Hello???".replaceAll("?", "!");
Hello!!!


Logged
Black Bart
Newbie
*
Posts: 5


« Reply #6 on: July 16, 2011, 07:22:07 am »



Is this a valid test?

"x".replaceAll("", "xyz");
xyzxxyz
Logged
qwerty
Newbie
*
Posts: 7


« Reply #7 on: July 16, 2011, 07:36:26 pm »

This is a correct test

"x".replaceAll("", "xyz");
xyzxxyz

The built in javascript function returns the following:

"x".replace("", "xyz");
xyzx

but it only replaces the first occurrence.
« Last Edit: July 16, 2011, 07:43:06 pm by qwerty » Logged
Black Bart
Newbie
*
Posts: 5


« Reply #8 on: July 18, 2011, 01:23:13 pm »

qwerty,

I found a problem with your replaceAll function.

It doesn't handle this case correctly:

"x".replaceAll("x", "$$");

It should return this
$$
But it returns this instead
$

Try again:)




Thanks Bailyn,

Let me know if you break it, or you have something better, but make sure it can pass these 4 tests:

"x".replaceAll("x", "xyz");
xyz

"x".replaceAll("", "xyz");
xyzxxyz

"aA".replaceAll("a", "b", true);
bb

"Hello???".replaceAll("?", "!");
Hello!!!



Logged
qwerty
Newbie
*
Posts: 7


« Reply #9 on: July 18, 2011, 04:45:45 pm »

Good find Bart,

This new version resolves the issue, and it's faster.

String.prototype.replaceAll = function(str1, str2, ignore)
{
   return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
};

Looks like I have a new test case
"x".replaceAll("x", "$$");
$$
Logged
qwerty
Newbie
*
Posts: 7


« Reply #10 on: July 20, 2011, 05:39:54 pm »

I'm going to repost this function as code:


Code:

String.prototype.replaceAll = function(str1, str2, ignore)
{
return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
};


« Last Edit: July 26, 2011, 03:29:13 am by qwerty » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!