Reputation: 4357
I'm pretty stumped on this recursive function. I'm using it to highlight words in a text box, but it's giving me some strange output:
should be:
#define
testing #define
but instead it's:
testing #define
testing #define
here's the code
function replace_all( text, old_str, new_str ){
index_of = text.indexOf( old_str );
if( index_of != -1 ){
old_text = text.substring( 0, index_of );
new_text = text.substring( index_of + old_str.length );
new_text = replace_all( new_text, old_str, new_str );
text = old_text + new_str + new_text;
}
return text;
}
Any ideas on what's wrong with the function? It seems to be replacing all the old keywords with the last one found.
Upvotes: 0
Views: 83
Reputation: 324650
Converting my comment to an answer:
This would be a lot easier like so:
function replace_all(text,old_str,new_str) {
var old_regex = old_str).replace(/[.\\+*?\[\^\]$(){}=!<>|:-]/g, '\\$&');
// the above line escapes any characters that may interfere with regex behaviour
return text.replace(new RegExp(old_regex,"g"),new_str);
}
Upvotes: 1
Reputation: 707436
You need to at least declare all your variables in the function as local variables by adding var
in front of their first use.
function replace_all( text, old_str, new_str ){
var index_of = text.indexOf( old_str );
if( index_of != -1 ){
var old_text = text.substring( 0, index_of );
var new_text = text.substring( index_of + old_str.length );
new_text = replace_all( new_text, old_str, new_str );
text = old_text + new_str + new_text;
}
return text;
}
By not using var
, your variables are global and each invocation of replace_all
will be sharing the same copies of variables which will mess up the recursion as recursive calls will mess up the state of the higher levels calls. If the variables are all local variables, then each function invocation has it's own set of variables and one recursive call does not mess up the others.
Plus, it is generally always a good idea to limit the scope of your variables to as local a scope as practical and avoid globals whenever possible. Implicit globals variables like you have here are particular evil because they can easily lead to accidental misuse.
As Kolink suggested, you might just want to do a single global .replace()
operation using a regex search/replace. You would need to make sure that any regex special characters in the search string were properly escaped though.
Upvotes: 3