具有递归功能的程序

时间:2013-04-01 04:35:03

标签: javascript string parsing recursion

我对这个递归函数感到非常难过。我用它来突出显示文本框中的单词,但它给了我一些奇怪的输出:

 should be:
 #define
 testing #define

 but instead it's:

 testing #define
 testing #define

这是代码

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;
}

关于功能有什么问题的任何想法?它似乎正在用找到的最后一个关键字替换所有旧关键字。

2 个答案:

答案 0 :(得分:3)

您需要在首次使用前添加var,至少将函数中的所有变量声明为局部变量。

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;
}

通过不使用var,你的变量是全局的,replace_all的每个调用将共享相同的变量副本,这会弄乱递归,因为递归调用会搞乱更高的状态水平电话。如果变量都是局部变量,那么每个函数调用都有自己的一组变量,一个递归调用不会弄乱其他变量。

另外,将变量的范围限制为实际的局部范围通常总是一个好主意,并尽可能避免使用全局变量。像你这样的隐含全局变量是特别邪恶的,因为它们很容易导致意外误用。

正如Kolink建议的那样,您可能只想使用正则表达式搜索/替换来执行单个全局.replace()操作。您需要确保搜索字符串中的任何正则表达式特殊字符都已正确转义。

答案 1 :(得分:1)

将我的评论转换为答案:

这样会更容易:

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);
}