【问题标题】:program with recursive function具有递归函数的程序
【发布时间】:2013-03-22 04:29:10
【问题描述】:

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

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

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

【问题讨论】:

  • function replace_all(text,ostr,nstr) {return text.replace(new RegExp(ostr,"g"),nstr);} 有什么问题?
  • 你是怎么调用replace_all函数的?
  • @Kolink 成功了。我从来没有查找过正则表达式,但它似乎可以完成这项工作。

标签: javascript string parsing recursion


【解决方案1】:

您至少需要将函数中的所有变量声明为局部变量,方法是在首次使用前添加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() 操作。不过,您需要确保搜索字符串中的任何正则表达式特殊字符都已正确转义。

【讨论】:

  • 这是有道理的。我认为这正在发生,但不知道这是使用 var 之间的区别
【解决方案2】:

将我的评论转换为答案:

这样会容易得多:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2011-07-21
    相关资源
    最近更新 更多