Use PHP functions in JavaScript

JavaScript str_replace

Replaces all occurrences of search in haystack with replace

1
2
3
4
56
7
8
9
1011
12
13
14
1516
17
18
19
2021
22
23
24
2526
27
28
29
3031
32
33
34
3536
37
38
39
4041
42
43
44
4546
47
48
49
5051
52
53
54
5556
function str_replace (search, replace, subject, count) {
    // Replaces all occurrences of search in haystack with replace  
    // 
    // version: 1109.2015
    // discuss at: http://phpjs.org/functions/str_replace    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Gabriel Paderni
    // +   improved by: Philip Peterson
    // +   improved by: Simon Willison (http://simonwillison.net)
    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)    // +   bugfixed by: Anton Ongson
    // +      input by: Onno Marsman
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +    tweaked by: Onno Marsman
    // +      input by: Brett Zamir (http://brett-zamir.me)    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   input by: Oleg Eremeev
    // +   improved by: Brett Zamir (http://brett-zamir.me)
    // +   bugfixed by: Oleg Eremeev
    // %          note 1: The count parameter must be passed as a string in order    // %          note 1:  to find a global variable in which the result will be given
    // *     example 1: str_replace(' ', '.', 'Kevin van Zonneveld');
    // *     returns 1: 'Kevin.van.Zonneveld'
    // *     example 2: str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
    // *     returns 2: 'hemmo, mars'    var i = 0,
        j = 0,
        temp = '',
        repl = '',
        sl = 0,        fl = 0,
        f = [].concat(search),
        r = [].concat(replace),
        s = subject,
        ra = Object.prototype.toString.call(r) === '[object Array]',        sa = Object.prototype.toString.call(s) === '[object Array]';
    s = [].concat(s);
    if (count) {
        this.window[count] = 0;
    } 
    for (i = 0, sl = s.length; i < sl; i++) {
        if (s[i] === '') {
            continue;
        }        for (j = 0, fl = f.length; j < fl; j++) {
            temp = s[i] + '';
            repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
            s[i] = (temp).split(f[j]).join(repl);
            if (count && s[i] !== temp) {                this.window[count] += (temp.length - s[i].length) / f[j].length;
            }
        }
    }
    return sa ? s : s[0];}
external links: original PHP docs | raw js source

Examples

» Example 1

Running

1
str_replace(' ', '.', 'Kevin van Zonneveld');

Should return

1
'Kevin.van.Zonneveld'

» Example 2

Running

1
str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');

Should return

1
'hemmo, mars'

Dependencies

No dependencies, you can use this function standalone.

Open syntax issues

php.js uses JsLint to help us keep our code consistent and prevent some common bugs.

Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.


Authors

Thanks to the following developers, you get to have str_replace goodness in JavaScript.

Comments

Add Comment
Use:
[CODE]
your_stuff('here');
[/CODE]
for proper code formatting
By submitting code here you are allowing us to use it in php.js hence dual licensing it under the MIT and GPL licenses

Gravatar
Michal
7 Nov '11 Permalink

q  If you like short scripts, use this modified function working same as one in PHP:

function str_replace (f, r, s) {f=[].concat(f), r=[].concat(r); for(var i in f){s=s.split(f[i]).join(r[r[i]!=undefined?i:0]);} return s;}


Note: it is evident f is search, r is replace and s is subject.
Enjoy!

Gravatar
Al Newmann
1 Sep '11 Permalink

q  For the very basic functionallity of the str_replace() function as shown in Example 1 there are two way easier and shorter solutions:

1)

     var cadena = "Cry%20of%20the%20Black%20Birds";
     cadena.split("%20").join(" ");
     // result : cadena == "Cry of the Black Birds"
    



2)

     var cadena = "Cry%20of%20the%20Black%20Birds";
     cadena.replaceAll("%20"," ");
     // result : cadena == "Cry of the Black Birds"
    



The code shown in the OP is very good and covers the whole functionallity of the str_replace() function, but if you are only looking for the basic of it, maybe you want to try these out.

Al.

Gravatar
Oziam
22 Jan '11 Permalink

q  This is my equivalent to PHP str_ireplace, it will search a given string for bad characters contained in an Array and replace if found. It will strip ALL upper & lowercase instances from string.

// Author: Oziam

function str_ireplace(str){
var bad = new Array('cc:','to:','content-type','href','\\n+','\\r+','\\t+','%0a+','%0d+','%08+','%09+');
var replace = "";
var result = "";
var x;
var  oldi = 0;
for (x in bad){
for (i = str.toLowerCase().indexOf(bad[x]); i > -1; i = str.toLowerCase().indexOf(bad[x],i)){
result += str.substring(oldi,i);
result += replace;
i += bad[x].length;
oldi = i;}
}
return result+str.substring(oldi,str.length);
}



Usage:
====

var string = "Send to: cc: bcc: etc.....";

str_ireplace(string);

returns;

Send etc.....

Gravatar
bajick
10 Dec '10 Permalink

q  Thank you so much! Nice work!

Gravatar
Brett Zamir
2 Nov '10 Permalink

q  @Ghabriel: Normally, you can leave comments on the "Add Function" page as you did or if it is a modification, you can leave it on the relevant function's page.

But in this case, my point is that our existing code in our "workbench" nor your code adequately meets our requirement of matching PHP behavior as closely as possible so we are not intending to release anything publicly until it meets the requirements I mentioned. We thank you for offering though, and you're welcome to try to meet the conditions I mentioned, but it would require quite a bit of JavaScript knowledge (and effort) in this case.

Gravatar
Ghabriel Nunes
1 Nov '10 Permalink

q  So, I need to go to somewhere to post my function or someone will do it for me?

Gravatar
Brett Zamir
1 Nov '10 Permalink

q  @Ghabriel Nunes: Thanks for submitting. If you go to our functions page and see the link to the missing functions (at http://phpjs.org/unported/index ), you can see functions like preg_replace which may have already been implemented in some form (or just go to Github directly). I'm kind of holding off on doing much with these, personally speaking, until we (or someone) will incorporate the powerful XRegExp.com code into these preg_* functions. And you can see http://github.com/kvz/phpjs/blob/master/_workbench/pcre/preg_match.js for a skeleton of how I'd hoped we could eventually implement other PHP regex features not even supported yet in XRegExp: http://github.com/kvz/phpjs/blob/master/_workbench/pcre/preg_match.js . (Basically PHP regex has a lot more we'd like to see made available than JavaScript allows natively, so it's a bit of work to really get it working closer to that reality.)

@Kevin: Seems the site has lost cookies now for a while. An easy way to put that back? Also, btw, it seems like your site is now unavailable from China without a proxy because one of the scripts is loading bit.ly content apparently.

Gravatar
Ghabriel Nunes
31 Oct '10 Permalink

q  Hi, I did make a preg_replace() function (it have the parameters: pattern, replacement, subject, limit) that doesn't use the eval() function (so it's better in terms of performance). I don't know if here is the right place, but I'll post it:

Example 1: preg_replace(/Kevin/,'','Kevin Kevin van Zonneveld')
Returns 1: 'van Zonneveld'

Example 2: preg_replace(/Kevin/,'','Kevin Kevin van Zonneveld',1)
Returns 2: 'Kevin van Zonneveld'


function preg_replace(pattern,replacement,subject,limit){
	
	if (subject.match(pattern) == null){
		return subject;
	} else {
		if (!limit){
			p = pattern + '', m = '';
			if (p.match(/\/([^/]*)\/i/) != null){
				m = 'i';
			}
			p = p.replace(/\//g,'').replace(m,'');
	
			p = new RegExp(p,(m + 'g'));
			pattern = p;
			
			return subject.replace(pattern,replacement);
		} else {
			for (i = 0; i < limit; i++){
				subject = subject.replace(pattern,replacement);
			}
			return subject;
		}
	}
}



Gravatar
Kevin van Zonneveld
8 Sep '10 Permalink

q  @ losif: Your str_replace will produce different results from PHP's in some cases. Among things, this has to do with Philip's comment from 30 Mar '08

As for your is_array, we also want it to return true for associative arrays (which we use JavaScript objects for). So just testing for the Array constructor wil fail for:

names['first'] = 'losif';

if (is_array(names)) {
    // Won't reach. names is an object in JavaScript terms.
}

Gravatar
Iosif
6 Sep '10 Permalink

q  [CODE}
function is_array(obj)
{
if (obj.constructor.toString().indexOf("Array") == -1)
return false;
else
return true;
}
[/CODE]

Gravatar
Iosif
6 Sep '10 Permalink

q  

function str_replace(search, replace, subject)
{
	if(is_array(search)) 
	{
		if(is_array(replace))
		{
			for(i in search)
			{
				subject = subject.split(search[i]).join(replace[i]);
			}
		}
		else
		{
			for(i in search)
			{
				subject = subject.split(search[i]).join(replace);
			}
		}
	}
	else
	{
		subject = subject.split(search).join(replace);
	}

    return subject;
}

Gravatar
Kevin van Zonneveld
16 Aug '09 Permalink

q  @ Max: It has to do with speed & PHP compliance. Your function will produce different results from PHP's in some cases. Among things, this has to do with Philip's comment from 30 Mar '08

Gravatar
Max
12 Aug '09 Permalink

q  Why do you use such a complicated function?
I have this one in use and it works fine:

function str_replace(search, replace, subject) {
    return subject.split(search).join(replace);
}

Gravatar
Brett Zamir
10 Aug '09 Permalink

q  @Erik: Just use the latest version here now; I recall the code had some buggy behavior, so it was fixed not too long ago.

Gravatar
Erik
10 Aug '09 Permalink

q  One question: JSLint complains about

while (j = 0, i--) {
Problem at line 50 character 17: Expected ')' to match '(' from line 50 and instead saw ','.




Any idea how to fix this and the resulting errors in JSLint? Much appreciated!

Gravatar
Brett Zamir
8 May '09 Permalink

q  Ouch! Thanks! I fixed that, and also had a bug in the next for loop initialization. Ok now in SVN... Thanks again...

Gravatar
Oleg Eremeev
7 May '09 Permalink

q  You forgot to change i-- in for() loop to i++ (or ++i - no difference :) ).

Gravatar
Oleg Eremeev
7 May '09 Permalink

q  I am happy to help you! ;)

Gravatar
Brett Zamir
6 May '09 Permalink

q  @Oleg, as far as why the loop goes down, there is no good reason, except that I was kind of following the pattern that was there previously. :) I changed it to an ascending loop to follow convention and not raise the same question for others. I also optimized the for loops a little by checking for the length at the beginning of the loop instead of upon each iteration. Thanks!

Gravatar
Oleg Eremeev
5 May '09 Permalink

q  Oh, sorry! I have read the documentation on php.net. I thought count param limits count of replaces, but it only counts replaces. I wrote a complete delusion, sorry. :)

Gravatar
Oleg Eremeev
5 May '09 Permalink

q  Ok. Good job, the function is written very correctly. :)
But why:
[...for (i=s.length-1; i >= 0; i--) {...]
not:
[...for (i=0; i <= s.length-1; i++) {...]
??? String-array will be parsed from right to left? I don't know PHP function specification, but I think count param is used to count affected symbols from left to right, it's more useful. Am I right?

Gravatar
Brett Zamir
5 May '09 Permalink

q  See my changes at http://trac.phpjs.org/projects/phpjs/browser/trunk/functions/strings/str_replace.js . I've tested all the PHP examples, and they are all working. Note that count must be in string form, and must out of necessity reference a global.

Gravatar
Oleg Eremeev
4 May '09 Permalink

q  Hi Brett,

My code can convert extra items to empty strings too:[CODE]
function str_replace(search, replace, subject) {
var s = subject;
var f = [].concat(search);
var r = [].concat(replace);
var l = f.length;
var i = 0;

for (i=0; i<l; ++i)
{
s = s.split(f[i]).join((r[i]!=undefined)?r[i]:'');
}

return s;
}
[CODE]But I forgot about count param. It's more difficult. Anyway, I don't want it. :)

Gravatar
Brett Zamir
4 May '09 Permalink

q  Hi Oleg,

Thanks for pointing out the bug... There was also a bug in handling the subject as an array. Should be fixed in SVN now. I think I might have also fixed the comments.

Btw, we can't just use the shorter length since the PHP behavior is to allow a longer search array to have extra items be replaced by the empty string (i.e., the extra items do get replaced (removed)).

I also added the count param...

Gravatar
Oleg Eremeev
4 May '09 Permalink

q  Why Code is uploading not correctly???

Gravatar
Oleg Eremeev
4 May '09 Permalink

q  In previous post something wrong.

function str_replace(search, replace, subject) {
var s = subject;
var f = [].concat(search);
var r = [].concat(replace);
var l = (f.length>r.length) ? r.length : f.length;
var i = 0;

for (i=0; i<l; ++i)
{
	s = s.split(f[i]).join(r[i]);
}

return s;
}

Gravatar
Oleg Eremeev
4 May '09 Permalink

q   Hello. I downloaded yesterday php.full.js. Library is very good, thank you for proceeding. But I tried to use str_replace function. It works not properly. Function replaces all items of search array with first item of replace array found in subject string. I wrote modified function:

function str_replace(search, replace, subject) {
    var s = subject;
    var f = [].concat(search);
    var r = [].concat(replace);
    var l = (f.length>r.length) ? r.length : f.length;
    var i = 0;
	
    for (i=0; i<l; ++i)
    {
        s = s.split(f[i]).join(r[i]);
    }
	
    return s;
}



This one do all I want. I hope it is useful, but I am not sure is it correct.

Sorry for my bad English, I am schoolboy from Latvia.

Gravatar
Kevin van Zonneveld
21 Feb '09 Permalink

q  @ avel: Be sure to checkout http://phpjs.org, I'm making some progress there.

Gravatar
avel
20 Feb '09 Permalink

q  Thanks a lot for this blog. Is really usefull.

i'm from Barcelona and i'm a baby php programer and this php.js library look like so good.

note: my website is nearly in net.

Gravatar
jonze
30 Jan '09 Permalink

q  hello and congratulations for this article(and script also). I needed something like str_replace from php very fast done with javscript and seems that your script does that very well!

Regards!

Gravatar
Brett Zamir
22 Jan '09 Permalink

q  acimeha, yes, using the native JavaScript replace works fine for most cases, but this project aims to support PHP's behavior, which also allows arrays as inputs.

Gravatar
acimeha
22 Jan '09 Permalink

q  hi there !
consider this as solution for str_replace

str = str.replace(new RegExp(&quot;\n\r&quot;, 'gi'), &quot;\n&quot;);


best regards

Gravatar
Kevin van Zonneveld
1 Dec '08 Permalink

q  @ Onno Marsman &amp; T. Wild: It's not my preferred coding style either, we may need to refactor it some day so it will be more consistent to other code found in php.js

Gravatar
Onno Marsman
27 Nov '08 Permalink

q  No trouble at all! I guess you've misunderstood me. Like I said I also don't like that whole shorthand stuff. It's very hard to read indeed.

Gravatar
T.Wild
26 Nov '08 Permalink

q  IN REPLY TO Onno Marsman.
As I said 'I'm not the best JavaScript programmer in the world.' and what I submitted worked for me (well, almost, r+='' should have been r = r+'' etc) in my limited tests, and I was having trouble seeing what the original code was doing anyway - I don't particularly like the shorthand ways of writing ifs etc - that's why I converted s,r and f to strings to be sure.

Your code fix works fine and sorry for the trouble.

Gravatar
Onno Marsman
26 Nov '08 Permalink

q  To be clear: I've only changed the s[i] to (s[i]+'') in that line.

Gravatar
Onno Marsman
26 Nov '08 Permalink

q  T.Wild: I don't have time for testing right now but doesn't the following do the trick a bit better?
When you do pass an array you'd also want every element to be a string.
I don't see any need to convert r to string(s), but I could be wrong. I find the code a bit hard to read.
Why the whole variable name replacement thing anyway? I thought we have a compiler to do this. This only results in more code after compilation.


[CODE=&quot;Javascript&quot;]
while (s[i] = (s[i]+'').split(f[j]).join(ra ? r[j] || &quot;&quot; : r[0]), ++j in f){};
[/CODE]

Gravatar
T.Wild
26 Nov '08 Permalink

q  OOPS, I leaped before I looked at the code properly, this may be a better idea but I'm not the best JavaScript programmer in the world.
[CODE=&quot;Javascript&quot;]
var f = search, r = replace, s = subject;

var ra = r instanceof Array, sa = s instanceof Array, f = [].concat(f), r = [].concat(r), i = (s = [].concat(s)).length;

if(!ra){r+='';}
if(!sa){s+='';}
if(!(f instanceof Array)){f+='';}
[/CODE]

Gravatar
T.Wild
26 Nov '08 Permalink

q  I think the following line should should probably be changed from:
[CODE=&quot;Javascript&quot;]
var f = search, r = replace, s = subject;
[/CODE]
TO
[CODE=&quot;Javascript&quot;]
var f = search+'', r = replace+'', s = subject+'';
[/CODE]

Found this problem (if anyone is interested) when trying:
[CODE=&quot;Javascript&quot;]
str_replace(&quot;foo&quot;,&quot;baa&quot;,location);
//You get the same problem with
str_replace(34,9,123456);
[/CODE]

Gravatar
Kevin van Zonneveld
29 Sep '08 Permalink

q  @ Onno &amp; Anton: Both excellent points. Function updated. Thank you!

Gravatar
Onno Marsman
25 Sep '08 Permalink

q  Why be dependant on is_array when you could just use &quot;instanceof Array&quot; ? This probably saves a bit of performance too.

Gravatar
Anton Ongsono
25 Sep '08 Permalink

q  i have try to use this, but i five me error in FF 2.0.0.16 :
[CODE=&quot;text&quot;]
s[i] has no properties
[Break on this error] while (s[i] = s[i].split(f[j])....in(ra ? r[j] || &quot;&quot; : r[0]), ++j in f){};
[/CODE]
so that i tried to fixed like this :
[CODE=&quot;Javascript&quot;]
function str_replace(search, replace, subject) {
var f = search, r = replace, s = subject;
var ra = is_array(r), sa = is_array(s), f = [].concat(f), r = [].concat(r), i = (s = [].concat(s)).length;

while (j = 0, i--) {
if (s[i])
{
while (s[i] = s[i].split(f[j]).join(ra ? r[j] || &quot;&quot; : r[0]), ++j in f){};
};
};

return sa ? s : s[0];
}
[/CODE]

Gravatar
Anton Ongsono
25 Sep '08 Permalink

q  i have try to use this, but i five me error in FF 2 :
[CODE=&quot;text&quot;]
s[i] has no properties
[Break on this error] while (s[i] = s[i].split(f[j])....in(ra ? r[j] || &quot;&quot; : r[0]), ++j in f){};
[/CODE]

so that i tried to fixed like this :
[CODE=&quot;Javascript&quot;]
function str_replace(search, replace, subject) {
var f = search, r = replace, s = subject;
var ra = is_array(r), sa = is_array(s), f = [].concat(f), r = [].concat(r), i = (s = [].concat(s)).length;

while (j = 0, i--) {
if (s[i])
{
while (s[i] = s[i].split(f[j]).join(ra ? r[j] || &quot;&quot; : r[0]), ++j in f){};
}
};

return sa ? s : s[0];
}
[/CODE]

Gravatar
Kevin van Zonneveld
18 Apr '08 Permalink

q  @ Jonas Raoni: That's astonishing :D The non-overlapping approach was convincing enough for me not to take the effort to test if this was the actual mechanism of PHP. It would make sense though right? Anyway, I will reinstate your version Jonas Raoni, and adjust the test case. Thanks for all of your work! You too Peter, some functions come easy, some tend to be a little of a pain. But that's the challenge &amp; learning experience, right.

Gravatar
Philip
18 Apr '08 Permalink

q  That is incredibly weird... I was certain that PHP replaced all the stuff at once so as not to create overlap... ah well, I guess it's not like that after all. It was a cool function though :P

Gravatar
Jonas Raoni
18 Apr '08 Permalink

q  I didn't looked the comments before, I just saw the code was long and made a version :)~

But it's strange... What php version are you using? The following code, on php 5, gave me as output &quot;hemmo, mars&quot;:

echo str_replace(array('{name}', 'l'), array('hello', 'm'), '{name}, lars');

Gravatar
Philip Peterson
18 Apr '08 Permalink

q  Woah, I didn't see comments #16 or #15... hmm, I'm surprised, it definitely has merit, though...

Gravatar
Philip Peterson
18 Apr '08 Permalink

q  Wow... bravo is all I can say... that's more than 20x faster than my code, too, lol...

Gravatar
Kevin van Zonneveld
17 Apr '08 Permalink

q  @ Jonas Raoni: I've updated, committed, generated, deployed, tested, reverted, commited, generated &amp; deployed ;)

And srry dude but your str_replace did not survive Peter's testcase:
[CODE=&quot;Javascript&quot;]
// should return: hello, mars
str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
[/CODE]

More info in the comments here.
Guess I'll be needing those medals back ;) nah just kidding :)

Gravatar
Kevin van Zonneveld
17 Apr '08 Permalink

q  @ Jonas Raoni: That looks very promising :) I still have to test it but if you have reduced our function to this, preserving all of it's functionality, then you deserve 3 medals ;)


Contribute a New function