2013-04-01 68 views
0

我對這個遞歸函數非常難過。我用它來突出顯示文本框的話,但它給了我一些奇怪的輸出:遞歸函數程序

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

上有什麼錯功能的任何想法?它似乎正在用所找到的最後一個關鍵字取代所有舊關鍵字。

+1

這有什麼錯'函數replace_all(文字,OSTR,NSTR){回報text.replace(新正則表達式(OSTR, 「G」),NSTR);}'? –

+0

你怎麼調用'replace_all'函數? – Jace

+0

@Kolink工作。我從來沒有看過正則表達式,但似乎這樣做的工作。 – tay10r

回答

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()操作。您需要確保搜索字符串中的任何正則表達式特殊字符已正確轉義。

+0

這是有道理的。我以爲這是在發生,但不知道這是使用var的區別 – tay10r

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